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 / ZCPR2 / FIND.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  26KB  |  1,257 lines

  1. ; PROGRAM:  FIND
  2. ; AUTHOR:  RICHARD CONN
  3. ; VERSION:  1.1
  4. ; DATE:  25 July 83
  5. ; PREVIOUS VERSIONS: 1.0 (24 JULY 83)
  6.  
  7. VERS    EQU    11        ;version number
  8.  
  9. ;
  10. ;    FIND searches through all of the known disks for one or more
  11. ; files matching the passed file specification.  AFNs (Ambiguous File Names)
  12. ; are permitted.  FIND is invoked by the following command line:
  13. ;        FIND afn,afn,afn,... o
  14. ; where "afn" refers to the file sought and "o" is none or more of:
  15. ;        S - Include System Files
  16. ;    FIND may be installed by GENINS to restrict the disks and user
  17. ; areas searched.
  18. ;
  19.  
  20. ;
  21. ; System equates:
  22. ;
  23. BOOT    EQU    0000H        ;CP/M WARM BOOT JUMP VECTOR
  24. BDOS    EQU    BOOT+05H    ;CP/M BDOS CALL JUMP VECTOR
  25. TBUFF    EQU    BOOT+80H    ;DISK I/O BUFFER
  26. FCB    EQU    BOOT+5CH    ;DEFAULT FILE CONTROL BLOCK
  27. FCB2    EQU    BOOT+6CH    ;SECONDARY FILE CONTROL AREA
  28. CR    EQU    'M'-'@'        ;CTL-M FOR CARRIAGE RETURN
  29. LF    EQU    'J'-'@'        ;CTL-J FOR LINE FEED
  30. CTRLC    EQU    'C'-'@'        ;ABORT
  31. CTRLS    EQU    'S'-'@'        ;PAUSE
  32. ESIZE    EQU    12        ;12 BYTES/DIR ENTRY
  33.  
  34. ;
  35. ;    This program is Copyright (c) 1983 by Richard Conn
  36. ;    All Rights Reserved
  37. ;
  38. ;    ZCPR2 and its utilities, including this one, are released
  39. ; to the public domain.  Anyone who wishes to USE them may do so with
  40. ; no strings attached.  The author assumes no responsibility or
  41. ; liability for the use of ZCPR2 and its utilities.
  42. ;
  43. ;    The author, Richard Conn, has sole rights to this program.
  44. ; ZCPR2 and its utilities may not be sold without the express,
  45. ; written permission of the author.
  46. ;
  47.  
  48. ;
  49. ;  Branch to Start of Program
  50. ;
  51.     ORG    BOOT+100H
  52.     JMP    START
  53.  
  54. ;
  55. ;******************************************************************
  56. ;
  57. ;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
  58. ;
  59. ;    This data block precisely defines the data format for
  60. ; initial features of a ZCPR2 system which are required for proper
  61. ; initialization of the ZCPR2-Specific Routines in SYSLIB.
  62. ;
  63.  
  64. ;
  65. ;  EXTERNAL PATH DATA
  66. ;
  67. EPAVAIL:
  68.     DB    0FFH    ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
  69. EPADR:
  70.     DW    40H    ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
  71.  
  72. ;
  73. ;  INTERNAL PATH DATA
  74. ;
  75. INTPATH:
  76.     DB    0,0    ; DISK, USER FOR FIRST PATH ELEMENT
  77.             ; DISK = 1 FOR A, '$' FOR CURRENT
  78.             ; USER = NUMBER, '$' FOR CURRENT
  79.     DB    0,0
  80.     DB    0,0
  81.     DB    0,0
  82.     DB    0,0
  83.     DB    0,0
  84.     DB    0,0
  85.     DB    0,0    ; DISK, USER FOR 8TH PATH ELEMENT
  86.     DB    0    ; END OF PATH
  87.  
  88. ;
  89. ;  MULTIPLE COMMAND LINE BUFFER DATA
  90. ;
  91. MCAVAIL:
  92.     DB    0FFH    ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
  93. MCADR:
  94.     DW    0FF00H    ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
  95.  
  96. ;
  97. ;  DISK/USER LIMITS
  98. ;
  99. MDISK:
  100.     DB    4    ; MAXIMUM NUMBER OF DISKS
  101. MUSER:
  102.     DB    31    ; MAXIMUM USER NUMBER
  103.  
  104. ;
  105. ;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
  106. ;
  107. DOK:
  108.     DB    0FFH    ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
  109. UOK:
  110.     DB    0FFH    ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
  111.  
  112. ;
  113. ;  PRIVILEGED USER DATA
  114. ;
  115. PUSER:
  116.     DB    10    ; BEGINNING OF PRIVILEGED USER AREAS
  117. PPASS:
  118.     DB    'chdir',0    ; PASSWORD FOR MOVING INTO PRIV USER AREAS
  119.     DS    41-($-PPASS)    ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
  120.  
  121. ;
  122. ;  CURRENT USER/DISK INDICATOR
  123. ;
  124. CINDIC:
  125.     DB    '$'    ; USUAL VALUE (FOR PATH EXPRESSIONS)
  126.  
  127. ;
  128. ;  DMA ADDRESS FOR DISK TRANSFERS
  129. ;
  130. DMADR:
  131.     DW    80H    ; TBUFF AREA
  132.  
  133. ;
  134. ;  NAMED DIRECTORY INFORMATION
  135. ;
  136. NDRADR:
  137.     DW    00000H    ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
  138. NDNAMES:
  139.     DB    64    ; MAX NUMBER OF DIRECTORY NAMES
  140. DNFILE:
  141.     DB    'NAMES   '    ; NAME OF DISK NAME FILE
  142.     DB    'DIR'        ; TYPE OF DISK NAME FILE
  143.  
  144. ;
  145. ;  REQUIREMENTS FLAGS
  146. ;
  147. EPREQD:
  148.     DB    000H    ; EXTERNAL PATH?
  149. MCREQD:
  150.     DB    000H    ; MULTIPLE COMMAND LINE?
  151. MXREQD:
  152.     DB    0FFH    ; MAX USER/DISK?
  153. UDREQD:
  154.     DB    000H    ; ALLOW USER/DISK CHANGE?
  155. PUREQD:
  156.     DB    000H    ; PRIVILEGED USER?
  157. CDREQD:
  158.     DB    000H    ; CURRENT INDIC AND DMA?
  159. NDREQD:
  160.     DB    000H    ; NAMED DIRECTORIES?
  161. Z2CLASS:
  162.     DB    0    ; CLASS 0
  163.     DB    'ZCPR2'
  164.     DS    10    ; RESERVED
  165.  
  166. ;
  167. ;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
  168. ;
  169. ;******************************************************************
  170. ;
  171.  
  172. ;
  173. ;  Start of Program
  174. ;
  175. START:
  176. ;
  177.     LXI    H,0        ;SAVE STACK PTR
  178.     DAD    SP
  179.     SHLD    STACK
  180.     LXI    SP,STACK    ;SET STACK POINTER
  181.     CALL    GTBIOS        ;GET BIOS JUMP TABLE
  182.     CALL     HELLO        ;SIGN ON MESSAGE
  183.     CALL    HELPCHK        ;CHECK FOR AND PRINT HELP MESSAGE
  184.     CALL    OPTCHK        ;BUILD FILE NAME TABLE AND PROCESS OPTIONS
  185.     CALL    CRLF        ;NEW LINE
  186.     CALL    FIND        ;DO THE SEARCHES
  187.     CALL    BYE        ;SIGN OFF MESSAGE
  188. RETURN:
  189.     LHLD    STACK        ;QUIET RETURN
  190.     SPHL
  191.     RET
  192. ;
  193. ; ** Main Routines **
  194. ;
  195.  
  196. ;
  197. ; SAY WHO WE ARE
  198. ;
  199. HELLO:
  200.     CALL    PRINT
  201.     DB    'FIND, Version '
  202.     DB    (VERS/10)+'0','.',(VERS MOD 10)+'0'
  203.     DB    0
  204.     RET
  205. ;
  206. ;  CHECK FOR HELP REQUEST
  207. ;
  208. HELPCHK:
  209.     LDA    FCB+1        ;GET 1ST BYTE OF FILENAME
  210.     CPI    '/'        ;HELP?
  211.     JZ    HCK1
  212.     CPI    ' '        ;MAKE SURE IT IS NON-BLANK
  213.     RNZ            ;OK - KEEP GOING
  214. ;    
  215. ; IF NO FILE NAME IS SPECIFIED, ABORT WITH NOTICE
  216. ;
  217. HCK1:
  218.     CALL     PRINT
  219.     DB    CR,LF
  220.     DB    CR,LF,'    FIND is used to search through all logged-in disks'
  221.     DB    CR,LF,'for any files matching an ambiguous file name (wild'
  222.     DB    CR,LF,'cards ar permitted).  It is invoked as follows:'
  223.     DB    CR,LF,'        FIND afn,afn,afn,... o'
  224.     DB    CR,LF,'where "afn" is the ambigous file name to search for'
  225.     DB    CR,LF,'(as many afns as desired may be specified), and'
  226.     DB    CR,LF,'"o" is none or more of the following options:'
  227.     DB    CR,LF,'        S - Include System Files'
  228.     DB    CR,LF,'Drive prefixes (DU:) are ignored.'
  229.     DB    CR,LF
  230.     DB    0
  231.     JMP    RETURN
  232. ;
  233. ; CHECKS FOR S OPTION IN COMMAND LINE AND EXTRACTS FILE NAMES INTO TABLE
  234. ;
  235. OPTCHK:
  236.     XRA    A    ;TURN OFF FLAGS
  237.     STA    SYSTEM    ;NO SYSTEM FILES
  238.     STA    FFLAG    ;NO FILES FOUND
  239.     STA    ECOUNT    ;NO ENTRIES
  240.     STA    FNCOUNT    ;NO FILE NAMES
  241.     LXI    H,TBUFF    ;SCAN THRU TBUFF, BUILDING A FILE NAME TABLE
  242.     MOV    A,M    ;GET CHAR COUNT
  243.     INX    H    ;PT TO FIRST CHAR
  244.     PUSH    H    ;SAVE PTR
  245.     ADD    L    ;PT TO AFTER LAST CHAR
  246.     MOV    L,A
  247.     MVI    M,0    ;STORE ENDING ZERO
  248.     POP    H    ;GET PTR TO FIRST CHAR
  249.     CALL    SBLANK    ;SKIP BLANKS
  250.     LXI    D,FNTAB    ;PT TO TABLE
  251. FNLOOP:
  252.     PUSH    D    ;SAVE TABLE PTR
  253.     CALL    GETFN    ;EXTRACT FILE NAME
  254.     POP    D
  255.     PUSH    H
  256.     LXI    H,11    ;PT TO NEXT TABLE ENTRY
  257.     DAD    D
  258.     XCHG
  259.     POP    H
  260.     LDA    FNCOUNT    ;INCREMENT COUNT
  261.     INR    A
  262.     STA    FNCOUNT
  263.     MOV    A,M    ;GET TERMINATING CHAR
  264.     INX    H    ;PT TO NEXT
  265.     CPI    ','    ;ANOTHER FOLLOWS?
  266.     JZ    FNLOOP
  267.     DCX    H    ;POINT BACK TO DELIM
  268.     CALL    SBLANK    ;SKIP TO NON-BLANK
  269. OPTCK1:
  270.     MOV    A,M    ;GET OPTION
  271.     CALL    DELCHK    ;DONE IF DELIM
  272.     RZ
  273.     CPI    'S'    ;SYSTEM?
  274.     JZ    OPTCKS
  275.     CALL    PRINT
  276.     DB    CR,LF,'Invalid Option -- ',0
  277.     MOV    A,M
  278.     CALL    TYPE
  279.     JMP    HCK1
  280. OPTCKS:
  281.     MVI    A,0FFH    ;SET FLAG
  282.     STA    SYSTEM
  283.     INX    H
  284.     JMP    OPTCK1
  285. GETFN:
  286.     PUSH    D    ;FILL TARGET FCB
  287.     MVI    B,11    ;11 BYTES
  288.     MVI    A,' '    ;SPACE FILL
  289. GETFN0:
  290.     STAX    D    ;PUT SPACE
  291.     INX    D
  292.     DCR    B
  293.     JNZ    GETFN0
  294.     POP    D    ;PT TO ENTRY AGAIN
  295.     CALL    SCANCOL    ;SCAN FOR COLON
  296.     MVI    B,8    ;8 CHARS MAX
  297.     CALL    GETFN1    ;GET AND FILL ENTRY
  298.     MOV    A,M    ;GET CHAR
  299.     CPI    '.'    ;DELIM?
  300.     RNZ        ;DONE
  301.     INX    H    ;PT TO AFTER PERIOD
  302.     MVI    B,3    ;3 CHARS MAX AND DO IT AGAIN
  303. GETFN1:
  304.     MOV    A,M    ;GET CHAR
  305.     CPI    '.'    ;END OF FIELD?
  306.     JZ    GETFN3
  307.     CALL    DELCHK    ;CHECK DELIMITER
  308.     RZ
  309.     CPI    '*'    ;WILD?
  310.     JZ    GETFNQ
  311.     STAX    D    ;STORE CHAR
  312.     INX    H    ;PT TO NEXT
  313.     INX    D
  314.     DCR    B    ;COUNT DOWN
  315.     JNZ    GETFN1
  316. GETFN2:
  317.     MOV    A,M    ;FLUSH CHARS TO DELIM
  318.     CALL    DELCHK    ;CHECK FOR DELIMITER
  319.     RZ
  320.     INX    H    ;PT TO NEXT
  321.     JMP    GETFN2
  322. GETFN3:
  323.     INX    D    ;PT TO AFTER FIELD
  324.     DCR    B    ;COUNT DOWN
  325.     JNZ    GETFN3
  326.     RET
  327. GETFNQ:
  328.     MVI    A,'?'    ;FILL WITH QUESTION MARKS
  329.     STAX    D
  330.     INX    D
  331.     DCR    B
  332.     JNZ    GETFNQ
  333.     JMP    GETFN2    ;SKIP TO DELIM
  334. DELCHK:
  335.     ORA    A    ;END OF LINE?
  336.     RZ
  337.     CPI    '.'    ;END OF FIELD?
  338.     RZ
  339.     CPI    ','    ;END OF ENTRY?
  340.     RZ
  341.     CPI    ' '
  342.     RET
  343. SBLANK:
  344.     MOV    A,M    ;SKIP TO NON-BLANK
  345.     CPI    ' '
  346.     RNZ
  347.     INX    H
  348.     JMP    SBLANK
  349. SCANCOL:
  350.     PUSH    D    ;SAVE TABLE PTR
  351.     PUSH    H    ;SAVE PTR
  352. SCOL1:
  353.     MOV    A,M    ;GET CHAR
  354.     INX    H    ;PT TO NEXT
  355.     CPI    ':'    ;COLON?
  356.     JZ    SCOLX
  357.     CALL    DELCHK    ;CHECK FOR DELIMITER
  358.     JNZ    SCOL1
  359. SCOL2:
  360.     POP    H    ;RESTORE
  361.     POP    D
  362.     RET
  363. SCOLX:
  364.     XCHG        ;DE PTS TO AFTER COLON
  365.     POP    H    ;GET OLD PTR
  366.     XCHG        ;REPLACE IT
  367.     POP    D    ;GET TABLE PTR
  368.     RET
  369. ;
  370. ; LOOK THROUGH DIRECTORY
  371. ;
  372. FIND:
  373.     XRA    A        ;SELECT FIRST DISK
  374.     STA    FCB
  375.     CALL    CPMCHK        ;GET INFO THE FIRST TIME
  376. FIND1:
  377.     RZ            ;ABORT IF ERROR
  378. FIND2:
  379.     CALL    NXTSEC        ;GET A DIRECTORY SECTOR
  380.     JZ    FIND3        ;RETURNS ZERO FLAG IF NO MORE
  381.     CALL    CHKENT        ;CHECK IT OUT
  382.     JMP    FIND2        ;KEEP IT UP TILL DONE
  383. FIND3:
  384.     CALL    DIRALPHA    ;SORT ENTRIES
  385.     CALL    PRFILES        ;PRINT SORTED ENTRIES
  386.     LDA    FCB        ;NEXT DISK
  387.     INR    A
  388.     STA    FCB
  389.     CALL    NXTDISK        ;SELECT NEXT DISK
  390.     JMP    FIND1
  391.  
  392. ;
  393. ; SIGN OFF
  394. ;
  395. BYE:
  396.     MVI    C,13        ;RESET SYSTEM
  397.     CALL    BDOS
  398.     LDA    FFLAG        ;GET FILE FOUND FLAG
  399.     ORA    A        ;NO FILES FOUND?
  400.     JNZ    RETURN
  401.     CALL    PRINT
  402.     DB    CR,LF,'NO Files Found',0
  403.     JMP    RETURN
  404. ;
  405. ; CHECKS THE CURRENT 4 DIRECTORY ENTRIES AGAINST ARGUMENT
  406. ; IF MATCH, REWRITES SECTOR WITH REACTIVATED 1ST BYTES
  407. ;
  408. CHKENT:
  409.     MVI    B,4        ;NUMBER OF ENTRIES PER SECTOR
  410.     LXI     H,TBUFF        ;BEGINNING OF BUFFER
  411. CKLUP:
  412.     PUSH    B
  413.     MOV    A,M
  414.     CPI    0E5H        ;CHECK FOR UNUSED
  415.     JZ    CKINC
  416.     XRA    A        ;A=0
  417.     STA    CLPFLG        ;SET FLAG FOR NO ENTRIES FOUND
  418.     LDA    FNCOUNT        ;GET NUMBER OF FILE NAMES TO LOOK THRU
  419.     MOV    B,A        ;... IN B
  420.     LXI    D,FNTAB        ;PT TO TABLE
  421. CKLUP1:
  422.     PUSH    B        ;SAVE COUNT
  423.     PUSH     H        ;SAVE BEGINNING ADDRESS
  424.     PUSH    D
  425.     CALL    COMPAR        ;COMPARE WITH ARGUMENT AND SAVE IF MATCH
  426.     POP    D
  427.     LXI    H,11        ;PT TO NEXT ENTRY
  428.     DAD    D
  429.     XCHG
  430.     POP    H
  431.     POP    B
  432.     DCR    B        ;COUNT DOWN
  433.     JNZ    CKLUP1
  434. CKINC:
  435.     POP    B
  436.     LXI    D,32        ;LENGTH OF ENTRY
  437.     DAD    D
  438.     DCR    B
  439.     JNZ    CKLUP
  440.     LHLD    DIRMAX
  441.     DCX    H        ;REDUCE SECTORS LEFT
  442.     SHLD    DIRMAX
  443.     LHLD    SECTOR        ;POINT TO NEXT SECTOR
  444.     INX    H
  445.     SHLD    SECTOR
  446.     XCHG
  447.     LHLD    MAXSEC        ;REACHED LIMIT?
  448.     INX    H        ;ONE MORE
  449.     MOV    A,H        ;CHECK HIGH
  450.     CMP    D
  451.     RNZ
  452.     MOV    A,L        ;CHECK LOW
  453.     CMP    E
  454.     RNZ
  455.     LHLD    TRACK        ;NEXT TRACK
  456.     INX    H
  457.     SHLD    TRACK
  458.     LXI    H,1        ;FIRST SECTOR OF NEXT TRACK
  459.     SHLD    SECTOR
  460.     RET
  461. ;
  462. ; COMPARE 11 BYTES OF DIRECTORY ENTRY AGAINST ARGUMENT; RNZ IF NOT MATCHED
  463. ;  DE PTS TO TABLE ENTRY TO COMPARE TO
  464. ;
  465. COMPAR:
  466.     LDA    CLPFLG        ;GET FOUND FLAG
  467.     ORA    A        ;0=NO
  468.     RNZ
  469.     SHLD    TEMP        ;Hold pointer in case of match
  470.     INX    H
  471.     XCHG
  472.     MVI    B,11
  473. CMPR1:
  474.     LDAX    D        ;GET DIRECTORY ENTRY CHARACTER
  475.     ANI    7FH        ;STRIP ANY FLAGS
  476.     CMP    M
  477.     JZ    CMPR2
  478.     MOV    A,M
  479.     CPI    '?'
  480.     RNZ
  481. CMPR2:
  482.     INX    D
  483.     INX    H        ;BUMP TO NEXT CHARACTER
  484.     DCR    B
  485.     JNZ    CMPR1        ;LOOP FOR 11 CHARACTERS
  486.     PUSH    D        ;SAVE ENTRY PTR
  487.     LDAX    D        ;GET EXTENT IN B
  488.     MOV    B,A
  489.     LDA    EXTENT        ;GET EXTENT MASK
  490.     CMP    B
  491.     POP    D        ;GET ENTRY PTR
  492.     JC    CMPR4        ;NO MATCH
  493.     LDA    SYSTEM        ;INCLUDE SYSTEM FILES?
  494.     ORA    A        ;0=NO
  495.     JNZ    CMPR3
  496.     DCX    D        ;BACK UP 2 BYTES
  497.     DCX    D
  498.     LDAX    D        ;GET T2
  499.     ANI    80H        ;CHECK FOR SYS
  500.     RNZ
  501. CMPR3:
  502.     LHLD    TEMP        ;CHECK FOR USER LIMIT
  503.     LDA    MUSER        ;GET MAX USER
  504.     CMP    M        ;BEYOND MAX?
  505.     JC    CMPR4
  506.     LHLD    FCOUNT        ;INCREMENT COUNT
  507.     INX    H
  508.     SHLD    FCOUNT
  509.     LHLD    DSTART        ;GET PTR TO NEXT ENTRY
  510.     XCHG
  511.     LHLD    TEMP
  512.     MVI    B,ESIZE        ;COPY ENTRY
  513.     CALL    MOVE
  514.     XCHG
  515.     SHLD    DSTART        ;PTR TO NEXT ENTRY
  516.     XCHG
  517.     LHLD    BDOS+1        ;CHECK FOR MEMORY OVERFLOW
  518.     MOV    A,H
  519.     SUI    10        ;BELOW CCP
  520.     CMP    D        ;PT BEYOND LIMIT?
  521.     JC    MOVFL
  522.     MVI    A,0FFH        ;SET FOUND FLAG
  523.     STA    FFLAG
  524.     XRA    A
  525.     RET            ;RETURNS 'ZERO' FLAG SET FOR MATCH
  526. CMPR4:
  527.     MVI    A,0FFH        ;NO MATCH
  528.     ORA    A
  529.     RET
  530. MOVFL:
  531.     CALL    PRINT
  532.     DB    CR,LF,'ABORT -- Not Enough Memory for Buffers',0
  533.     JMP    RETURN
  534. ;
  535. ; CHECK FOR CP/M VERSION AND SET THINGS
  536. ;
  537. CPMCHK:
  538.     MVI    C,12        ;VERSION NUMBER REQUEST
  539.     CALL     BDOS
  540.     CPI    20H        ;EARLIER THAN 2.2?
  541.     JC    VERERR
  542. ;
  543. ;  ADVANCE TO NEXT DISK
  544. ;
  545. NXTDISK:
  546.     LXI    B,TBUFF        ;SET DMA ADDRESS
  547.     CALL    SETDMA
  548.     LDA    MDISK        ;GET MAX DISK
  549.     MOV    B,A
  550.     LDA    FCB
  551.     CMP    B
  552.     RZ            ;ABORT IF BEYOND MAX
  553.     MOV    C,A
  554.     MVI    B,0
  555.     CALL    SELDSK        ;MAKE SURE DRIVE IS
  556.     MOV    A,H        ;  SELECTED
  557.     ORA    L
  558.     RZ            ;ERROR RETURN
  559.     SHLD    DPH        ;SAVE THE ADDRESS
  560.     LXI    D,10        ;PT TO DPB
  561.     DAD    D
  562.     MOV    E,M        ;GET DPB ADDRESS IN HL
  563.     INX    H
  564.     MOV    D,M
  565.     XCHG
  566.     MOV    E,M        ;NUMBER OF SECTORS/TRACK
  567.     INX    H        ;AS 2-BYTE QUANTITY IN DE
  568.     MOV    D,M
  569.     INX    H
  570.     XCHG
  571.     SHLD    MAXSEC        ;SET MAX SECTORS/TRACK
  572.     XCHG
  573.     INX    H
  574.     INX    H
  575.     MOV    A,M        ;GET EXM
  576.     STA    EXTENT
  577.     INX    H        ;PT TO DRM
  578.     INX    H
  579.     INX    H
  580.     MOV    E,M        ;GET NUMBER OF
  581.     INX    H        ;  DIRECTORY ENTRIES
  582.     MOV    D,M
  583.     XCHG
  584.     INX    H        ;ACCOUNT FOR - 1
  585.     SHLD    DSTART        ;SAVE NUMBER OF DIRECTORY ENTRIES
  586.     CALL    SHFHL2        ;SHIFT 'HL' RIGHT 2
  587.     SHLD    DIRMAX        ;SAVE NUMBER DIRECTORY SECTORS
  588.     LXI    H,5        ;NOW POINT TO SYSTEM
  589.     DAD    D        ;  TRACK OFFSET
  590.     MOV    A,M        ;PICK UP NUMBER OF
  591.     INX    H
  592.     MOV    H,M
  593.     MOV    L,A
  594.     SHLD    TRACK
  595.     LXI    H,1        ;SET SECTOR
  596.     SHLD    SECTOR
  597.     LDA    ECOUNT        ;LAST NEW LINE?
  598.     ANI    3
  599.     CNZ    CRLF
  600.     CALL    PRINT
  601.     DB    'Disk ',0
  602.     LDA    FCB
  603.     ADI    'A'
  604.     CALL    TYPE
  605.     CALL    PRINT
  606.     DB    ' --',CR,LF,0
  607.     LXI    H,SCRATCH    ;PT TO SCRATCH AREA
  608.     SHLD    ORDER        ;ADDRESS OF ORDER TABLE
  609.     XCHG
  610.     LHLD    DSTART        ;GET NUMBER OF DIRECTORY ENTRIES
  611.     DAD    H        ;DOUBLE FOR NUMBER OF BYTES IN ORDER TABLE
  612.     DAD    D        ;PT TO FIRST BYTE OF DIRBUF
  613.     SHLD    DIRBUF        ;SET PTR
  614.     SHLD    DSTART        ;SET LOOP PTR
  615.     LXI    H,0        ;SET FILE COUNT
  616.     SHLD    FCOUNT
  617.     XRA    A        ;SET COUNT
  618.     STA    ECOUNT
  619.     CMA            ;FLIP
  620.     ORA    A        ;OK TO CONTINUE
  621.     RET
  622. VERERR:
  623.     CALL    PRINT
  624.     DB    CR,LF,'ABORT -- NOT CP/M 2.x or Later',0
  625.     JMP    RETURN
  626. ;
  627. ; GET BIOS JUMPS VECTORS FOR EASY REFERENCE
  628. ;
  629. GTBIOS:
  630.     LHLD    BOOT+1        ;POINTS TO BIOS JUMP TABLE+3
  631.     LXI    D,WBOOT        ;WHERE WE WILL KEEP A COPY
  632.     MVI    B,16*3        ;MOVE 48 BYTES AND FALL THRU TO MOVE
  633. ;
  634. ; GENERAL PURPOSE MOVE ROUTINE
  635. ; FROM 'HL' TO 'DE' FOR COUNT OF 8
  636. ;
  637. MOVE:
  638.     MOV    A,M        ;GET A BYTE
  639.     STAX    D        ;PUT A BYTE
  640.     INX    D        ;INCREMENT TO NEXT
  641.     INX    H
  642.     DCR    B        ;COUNT DOWN
  643.     JNZ    MOVE
  644.     RET
  645. ;
  646. ; READS NEXT SECTOR (GROUP OF FOUR DIRECTORY ENTRIES)
  647. ; RETURNS WITH ZERO FLAG SET IF NO MORE
  648. ;
  649. NXTSEC:
  650.     LHLD    DIRMAX        ;SEE IF MORE SECTORS
  651.     MOV    A,H
  652.     ORA    L
  653.     RZ            ;RETURNS ZERO FLAG IF NO MORE
  654.     LHLD    TRACK        ;SET TRACK
  655.     MOV    B,H
  656.     MOV    C,L
  657.     CALL    SETTRK
  658.     LHLD    SECTOR        ;SET SECTOR
  659.     MOV    B,H
  660.     MOV    C,L
  661.     CALL    TRNSLT
  662.     CALL    SETSEC
  663.     CALL    READ        ;READ A SECTOR
  664.     ANI    1        ;REVERSE SENSE OF ERROR FLAG
  665.     XRI    1        ;RETURNS WITH ZERO FLAG SET
  666.     RET            ;IF BAD READ
  667. ;
  668. ; PRINT FILES IN DIRBUF
  669. ;
  670. PRFILES:
  671.     LHLD    FCOUNT        ;GET COUNT
  672.     MOV    A,H        ;ANY?
  673.     ORA    L
  674.     RZ
  675.     MOV    B,H        ;COUNT IN BC
  676.     MOV    C,L
  677.     LHLD    DIRBUF        ;PT TO FIRST ONE
  678. PRFLOOP:
  679.     PUSH    B        ;SAVE COUNT
  680.     PUSH    H        ;SAVE PTR
  681.     CALL    PRINTFCB    ;PRINT FCB
  682.     POP    H        ;GET REGS BACK
  683.     POP    B
  684.     LXI    D,ESIZE        ;PT TO NEXT
  685.     DAD    D
  686.     DCX    B        ;COUNT DOWN
  687.     MOV    A,B
  688.     ORA    C
  689.     JNZ    PRFLOOP
  690.     MVI    A,0FFH        ;SET OK
  691.     ORA    A
  692.     RET
  693. ;
  694. ; FCB PRINTING ROUTINE
  695. ;
  696. PRINTFCB:
  697.     MVI    A,' '        ;SPACE IN
  698.     CALL    TYPE
  699.     CALL    TYPE
  700.     MOV    A,M        ;GET USER NUMBER
  701.     CALL    DECOUT        ;PRINT IT
  702.     MVI    A,':'
  703.     CALL    TYPE
  704.     INX    H
  705. PR0:
  706.     MVI    B,8
  707.     CALL    PR1
  708.     MVI    A,'.'
  709.     CALL    TYPE
  710.     MVI    B,3
  711.     CALL    PR1
  712.     LDA    ECOUNT        ;INCREMENT COUNT
  713.     INR    A
  714.     STA    ECOUNT
  715.     ANI    3        ;EVERY 4
  716.     CZ    CRLF        ;NEW LINE
  717.     RET
  718. PR1:
  719.     MOV    A,M
  720.     ANI    7FH
  721.     CALL    TYPE
  722.     INX    H
  723.     DCR    B
  724.     JNZ    PR1    
  725.     RET
  726. ;
  727. ;  PRINT VALUE IN A AS DECIMAL
  728. ;
  729. DECOUT:
  730.     PUSH    B    ;SAVE REG
  731.     MVI    C,'0'    ;SET VALUE
  732. DEC1:
  733.     SUI    10    ;DIVIDE BY 10
  734.     JC    DEC2
  735.     INR    C
  736.     JMP    DEC1
  737. DEC2:
  738.     ADI    10    ;ADD 10 BACK IN
  739.     MOV    B,A    ;SAVE VALUE
  740.     MOV    A,C    ;CHECK DIGITS
  741.     CPI    '0'
  742.     JNZ    DEC3
  743.     MVI    A,' '    ;LEADING SPACE
  744. DEC3:
  745.     CALL    TYPE    ;DON'T TYPE LEADING ZERO
  746.     MOV    A,B    ;GET ONES
  747.     ADI    '0'    ;CONVERT TO ASCII
  748.     CALL    TYPE
  749.     POP    B    ;GET REG
  750.     RET
  751. ;
  752. ;  PRINT CHAR IN A ON TERMINAL; AFFECT NO REGS
  753. ;
  754. TYPE:
  755.     PUSH    H    ;SAVE REGS
  756.     PUSH    D
  757.     PUSH    B
  758.     PUSH    PSW
  759.     CALL    CONST    ;CHAR PENDING?
  760.     ORA    A    ;0=NONE
  761.     JZ    TYPE1
  762.     CALL    CONIN    ;GET CHAR
  763.     ANI    7FH    ;MASK
  764.     CPI    CTRLC    ;ABORT?
  765.     JZ    RETURN
  766.     CPI    CTRLS    ;PAUSE?
  767.     JNZ    TYPE1
  768.     CALL    CONIN    ;GET ANOTHER CHAR
  769.     CPI    CTRLC
  770.     JZ    RETURN
  771. TYPE1:
  772.     POP    PSW    ;GET CHAR TO SEND
  773.     PUSH    PSW
  774.     MOV    C,A    ;CHAR IN C
  775.     CALL    CONOUT
  776.     POP    PSW    ;RESTORE REGS
  777.     POP    B
  778.     POP    D
  779.     POP    H
  780.     RET
  781. ;
  782. ;  NEW LINE
  783. ;
  784. CRLF:
  785.     MVI    A,0DH        ;NEW LINE
  786.     CALL    TYPE
  787.     MVI    A,0AH
  788.     JMP    TYPE
  789. ;
  790. ;  PRINT MESSAGE AT RETURN ADDRESS
  791. ;
  792. PRINT:
  793.     XTHL            ;SAVE HL, GET PTR
  794. PRINTL:
  795.     MOV    A,M        ;GET BYTE
  796.     INX    H        ;PT TO NEXT
  797.     ANI    7FH        ;MASK
  798.     JZ    PRINTD        ;DONE IF ZERO
  799.     CALL    TYPE
  800.     JMP    PRINTL
  801. PRINTD:
  802.     XTHL
  803.     RET
  804. ;
  805. ; SHIFT REGS 'HL' RIGHT 2 BITS LOGICAL
  806. ;
  807. SHFHL2:
  808.     CALL    SHFHL        ;ROTATE RIGHT 1 BIT AND FALL THRU
  809. SHFHL:
  810.     XRA    A        ;CLEAR CARRY
  811.     MOV    A,H
  812.     RAR            ;SHIFTED BIT IN CARRY
  813.     MOV    H,A
  814.     MOV    A,L
  815.     RAR
  816.     MOV    L,A
  817.     RET
  818. ;
  819. ; TRANSLATE REG 'BC' FROM LOGICAL TO PHYSICAL SECTOR NUMBER
  820. ;
  821. TRNSLT:
  822.     LHLD    DPH        ;GET PTR TO DPH
  823.     MOV    E,M        ;GET ADDRESS OF XLT
  824.     INX    H
  825.     MOV    D,M
  826.     CALL    SECTRAN        ;USE BIOS ROUTINE
  827.     MOV    C,L        ;RETURN VALUE IN BC
  828.     MOV    B,H
  829.     RET
  830.  
  831. ;
  832. ;  DIRALPHA -- ALPHABETIZES DIRECTORY PTED TO BY HL; BC CONTAINS
  833. ;    THE NUMBER OF FILES IN THE DIRECTORY
  834. ;
  835. DIRALPHA:
  836.     LHLD    FCOUNT    ; GET FILE COUNT
  837.     MOV    A,H    ; ANY FILES?
  838.     ORA    L
  839.     RZ
  840.     SHLD    N    ; SET "N"
  841.     MOV    B,H    ; BC=COUNT
  842.     MOV    C,L
  843.     LHLD    DIRBUF    ; PT TO DIRECTORY
  844. ;
  845. ;  SHELL SORT --
  846. ;    THIS SORT ROUTINE IS ADAPTED FROM "SOFTWARE TOOLS"
  847. ;    BY KERNIGAN AND PLAUGHER, PAGE 106.  COPYRIGHT, 1976, ADDISON-WESLEY.
  848. ;  ON ENTRY, BC=NUMBER OF ENTRIES AND HL=ADDRESS OF FIRST ENTRY
  849. ;
  850. SORT:
  851.     XCHG        ; POINTER TO DIRECTORY IN DE
  852.     LHLD    ORDER    ; PT TO ORDER TABLE
  853. ;
  854. ;  SET UP ORDER TABLE; HL PTS TO NEXT ENTRY IN ORDER TABLE, DE PTS TO NEXT
  855. ;    ENTRY IN DIRECTORY, BC = NUMBER OF ELEMENTS REMAINING
  856. ;
  857. SORT1:
  858.     MOV    M,E    ; STORE LOW-ORDER ADDRESS
  859.     INX    H    ; PT TO NEXT ORDER BYTE
  860.     MOV    M,D    ; STORE HIGH-ORDER ADDRESS
  861.     INX    H    ; PT TO NEXT ORDER ENTRY
  862.     PUSH    H    ; SAVE PTR
  863.     LXI    H,ESIZE    ; HL=NUMBER OF BYTES/ENTRY
  864.     DAD    D    ; PT TO NEXT DIR1 ENTRY
  865.     XCHG        ; DE PTS TO NEXT ENTRY
  866.     POP    H    ; GET PTR TO ORDER TABLE
  867.     DCX    B    ; COUNT DOWN
  868.     MOV    A,B    ; DONE?
  869.     ORA    C
  870.     JNZ    SORT1
  871. ;
  872. ;  THIS IS THE MAIN SORT LOOP FOR THE SHELL SORT IN "SOFTWARE TOOLS" BY K&P
  873. ;
  874.  
  875. ;
  876. ;  SHELL SORT FROM "SOFTWARE TOOLS" BY KERNINGHAN AND PLAUGER
  877. ;
  878.     LHLD    N    ; NUMBER OF ITEMS TO SORT
  879.     SHLD    GAP    ; SET INITIAL GAP TO N FOR FIRST DIVISION BY 2
  880.  
  881. ;  FOR (GAP = N/2; GAP > 0; GAP = GAP/2)
  882. SRTL0:
  883.     ORA    A    ; CLEAR CARRY
  884.     LHLD    GAP    ; GET PREVIOUS GAP
  885.     MOV    A,H    ; ROTATE RIGHT TO DIVIDE BY 2
  886.     RAR
  887.     MOV    H,A
  888.     MOV    A,L
  889.     RAR
  890.     MOV    L,A
  891.  
  892. ;  TEST FOR ZERO
  893.     ORA    H
  894.     JZ    SDONE    ; DONE WITH SORT IF GAP = 0
  895.  
  896.     SHLD    GAP    ; SET VALUE OF GAP
  897.     SHLD    I    ; SET I=GAP FOR FOLLOWING LOOP
  898.  
  899. ;  FOR (I = GAP + 1; I <= N; I = I + 1)
  900. SRTL1:
  901.     LHLD    I    ; ADD 1 TO I
  902.     INX    H
  903.     SHLD    I
  904.  
  905. ;  TEST FOR I <= N
  906.     XCHG        ; I IS IN DE
  907.     LHLD    N    ; GET N
  908.     MOV    A,L    ; COMPARE BY SUBTRACTION
  909.     SUB    E
  910.     MOV    A,H
  911.     SBB    D    ; CARRY SET MEANS I > N
  912.     JC    SRTL0    ; DON'T DO FOR LOOP IF I > N
  913.  
  914.     LHLD    I    ; SET J = I INITIALLY FOR FIRST SUBTRACTION OF GAP
  915.     SHLD    J
  916.  
  917. ;  FOR (J = I - GAP; J > 0; J = J - GAP)
  918. SRTL2:
  919.     LHLD    GAP    ; GET GAP
  920.     XCHG        ; ... IN DE
  921.     LHLD    J    ; GET J
  922.     MOV    A,L    ; COMPUTE J - GAP
  923.     SUB    E
  924.     MOV    L,A
  925.     MOV    A,H
  926.     SBB    D
  927.     MOV    H,A
  928.     SHLD    J    ; J = J - GAP
  929.     JC    SRTL1    ; IF CARRY FROM SUBTRACTIONS, J < 0 AND ABORT
  930.     MOV    A,H    ; J=0?
  931.     ORA    L
  932.     JZ    SRTL1    ; IF ZERO, J=0 AND ABORT
  933.  
  934. ;  SET JG = J + GAP
  935.     XCHG        ; J IN DE
  936.     LHLD    GAP    ; GET GAP
  937.     DAD    D    ; J + GAP
  938.     SHLD    JG    ; JG = J + GAP
  939.  
  940. ;  IF (V(J) <= V(JG))
  941.     CALL    ICOMPARE    ; J IN DE, JG IN HL
  942.  
  943. ;  ... THEN BREAK
  944.     JC    SRTL1
  945.  
  946. ;  ... ELSE EXCHANGE
  947.     LHLD    J    ; SWAP J, JG
  948.     XCHG
  949.     LHLD    JG
  950.     CALL    ISWAP    ; J IN DE, JG IN HL
  951.  
  952. ;  END OF INNER-MOST FOR LOOP
  953.     JMP    SRTL2
  954.  
  955. ;
  956. ;  SORT IS DONE -- RESTRUCTURE DIR1 IN SORTED ORDER IN PLACE
  957. ;
  958. SDONE:
  959.     LHLD    N    ; NUMBER OF ENTRIES
  960.     MOV    B,H    ; ... IN BC
  961.     MOV    C,L
  962.     LHLD    ORDER    ; PTR TO ORDERED POINTER TABLE
  963.     SHLD    PTPTR    ; SET PTR PTR
  964.     LHLD    DIRBUF    ; PTR TO UNORDERED DIRECTORY
  965.     SHLD    PTDIR    ; SET PTR DIR BUFFER
  966.  
  967. ;  FIND PTR TO NEXT DIR1 ENTRY
  968. SRTDN:
  969.     LHLD    PTPTR    ; PT TO REMAINING POINTERS
  970.     XCHG        ; ... IN DE
  971.     LHLD    PTDIR    ; HL PTS TO NEXT DIR ENTRY
  972.     PUSH    B    ; SAVE COUNT OF REMAINING ENTRIES
  973.  
  974. ;  FIND PTR TABLE ENTRY
  975. SRTDN1:
  976.     LDAX    D    ; GET CURRENT POINTER TABLE ENTRY VALUE
  977.     INX    D    ; PT TO HIGH-ORDER POINTER BYTE
  978.     CMP    L    ; COMPARE AGAINST DIR1 ADDRESS LOW
  979.     JNZ    SRTDN2    ; NOT FOUND YET
  980.     LDAX    D    ; LOW-ORDER BYTES MATCH -- GET HIGH-ORDER POINTER BYTE
  981.     CMP    H    ; COMPARE AGAINST DIR1 ADDRESS HIGH
  982.     JZ    SRTDN3    ; MATCH FOUND
  983. SRTDN2:
  984.     INX    D    ; PT TO NEXT PTR TABLE ENTRY
  985.     DCX    B    ; COUNT DOWN
  986.     MOV    A,C    ; END OF TABLE?
  987.     ORA    B
  988.     JNZ    SRTDN1    ; CONTINUE IF NOT
  989.  
  990. ;  FATAL ERROR -- INTERNAL ERROR; POINTER TABLE NOT CONSISTENT
  991. FERR$PTR:
  992.     CALL    PRINT
  993.     DB    0DH,0AH,'DIRALPHA -- Pointer Error',0
  994.     JMP    RETURN
  995.  
  996. ;  FOUND THE POINTER TABLE ENTRY WHICH POINTS TO THE NEXT UNORDERED DIR1 ENTRY
  997. ;    MAKE BOTH POINTERS (PTR TO NEXT, PTR TO CURRENT UNORDERED DIR1 ENTRY)
  998. ;    POINT TO SAME LOCATION (PTR TO NEXT DIR1 ENTRY TO BE ORDERED)
  999. SRTDN3:
  1000.     LHLD    PTPTR    ; GET PTR TO NEXT ORDERED ENTRY
  1001.     DCX    D    ; DE PTS TO LOW-ORDER POINTER ADDRESS
  1002.     MOV    A,M    ; MAKE PTR TO NEXT UNORDERED DIR1 PT TO BUFFER FOR
  1003.     STAX    D    ;   DIR1 ENTRY TO BE MOVED TO NEXT UNORDERED DIR1 POS
  1004.     INX    H    ; PT TO NEXT PTR ADDRESS
  1005.     INX    D
  1006.     MOV    A,M    ; MAKE HIGH POINT SIMILARLY
  1007.     STAX    D
  1008.  
  1009. ;  COPY NEXT UNORDERED DIR1 ENTRY TO HOLD BUFFER
  1010.     MVI    B,ESIZE    ; B=NUMBER OF BYTES/ENTRY
  1011.     LHLD    PTDIR    ; PT TO ENTRY
  1012.     LXI    D,HOLD    ; PT TO HOLD BUFFER
  1013.     PUSH    B    ; SAVE B=NUMBER OF BYTES/ENTRY
  1014.     CALL    MOVE
  1015.     POP    B
  1016.  
  1017. ;  COPY TO-BE-ORDERED DIR1 ENTRY TO NEXT ORDERED DIR1 POSITION
  1018.     LHLD    PTPTR    ; POINT TO ITS POINTER
  1019.     MOV    E,M    ; GET LOW-ADDRESS POINTER
  1020.     INX    H
  1021.     MOV    D,M    ; GET HIGH-ADDRESS POINTER
  1022.     LHLD    PTDIR    ; DESTINATION ADDRESS FOR NEXT ORDERED DIR1 ENTRY
  1023.     XCHG        ; HL PTS TO ENTRY TO BE MOVED, DE PTS TO DEST
  1024.     PUSH    B    ; SAVE B=NUMBER OF BYTES/ENTRY
  1025.     CALL    MOVE
  1026.     POP    B
  1027.     XCHG        ; HL PTS TO NEXT UNORDERED DIR1 ENTRY
  1028.     SHLD    PTDIR    ; SET POINTER FOR NEXT LOOP
  1029.  
  1030. ;  COPY ENTRY IN HOLD BUFFER TO LOC PREVIOUSLY HELD BY LATEST ORDERED ENTRY
  1031.     LHLD    PTPTR    ; GET PTR TO PTR TO THE DESTINATION
  1032.     MOV    E,M    ; GET LOW-ADDRESS POINTER
  1033.     INX    H
  1034.     MOV    D,M    ; HIGH-ADDRESS POINTER
  1035.     LXI    H,HOLD    ; HL PTS TO HOLD BUFFER, DE PTS TO ENTRY DEST
  1036.     CALL    MOVE    ; B=NUMBER OF BYTES/ENTRY
  1037.  
  1038. ;  POINT TO NEXT ENTRY IN POINTER TABLE
  1039.     LHLD    PTPTR    ; POINTER TO CURRENT ENTRY
  1040.     INX    H    ; SKIP OVER IT
  1041.     INX    H
  1042.     SHLD    PTPTR
  1043.  
  1044. ;  COUNT DOWN
  1045.     POP    B    ; GET COUNTER
  1046.     DCX    B    ; COUNT DOWN
  1047.     MOV    A,C    ; DONE?
  1048.     ORA    B
  1049.     JNZ    SRTDN
  1050.     RET        ; DONE
  1051.  
  1052. ;
  1053. ;  SWAP (Exchange) the pointers in the ORDER table whose indexes are in
  1054. ;    HL and DE
  1055. ;
  1056. ISWAP:
  1057.     PUSH    H        ; SAVE HL
  1058.     LHLD    ORDER        ; ADDRESS OF ORDER TABLE - 2
  1059.     MOV    B,H        ; ... IN BC
  1060.     MOV    C,L
  1061.     POP    H
  1062.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  1063.     DAD    H        ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX
  1064.                 ;   OF ORIGINAL HL (1, 2, ...)
  1065.     DAD    B        ; HL NOW PTS TO POINTER INVOLVED
  1066.     XCHG            ; DE NOW PTS TO POINTER INDEXED BY HL
  1067.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  1068.     DAD    H        ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX
  1069.                 ;   OF ORIGINAL DE (1, 2, ...)
  1070.     DAD    B        ; HL NOW PTS TO POINTER INVOLVED
  1071.     MOV    C,M        ; EXCHANGE POINTERS -- GET OLD (DE)
  1072.     LDAX    D        ; -- GET OLD (HL)
  1073.     XCHG            ; SWITCH
  1074.     MOV    M,C        ; PUT NEW (HL)
  1075.     STAX    D        ; PUT NEW (DE)
  1076.     INX    H        ; PT TO NEXT BYTE OF POINTER
  1077.     INX    D
  1078.     MOV    C,M        ; GET OLD (HL)
  1079.     LDAX    D        ; GET OLD (DE)
  1080.     XCHG            ; SWITCH
  1081.     MOV    M,C        ; PUT NEW (DE)
  1082.     STAX    D        ; PUT NEW (HL)
  1083.     RET
  1084. ;
  1085. ;  ICOMPARE compares the entry pointed to by the pointer pointed to by HL
  1086. ;    with that pointed to by DE (1st level indirect addressing); on entry,
  1087. ;    HL and DE contain the numbers of the elements to compare (1, 2, ...);
  1088. ;    on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)),
  1089. ;    and Non-Zero and No-Carry means ((DE)) > ((HL))
  1090. ;
  1091. ICOMPARE:
  1092.     PUSH    H        ; SAVE HL
  1093.     LHLD    ORDER        ; ADDRESS OF ORDER - 2
  1094.     MOV    B,H        ; ... IN BC
  1095.     MOV    C,L
  1096.     POP    H
  1097.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  1098.     DAD    H        ; DOUBLE THE ELEMENT NUMBER TO POINT TO THE PTR
  1099.     DAD    B        ; ADD TO THIS THE BASE ADDRESS OF THE PTR TABLE
  1100.     XCHG            ; RESULT IN DE
  1101.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  1102.     DAD    H        ; DO THE SAME WITH THE ORIGINAL DE
  1103.     DAD    B
  1104.     XCHG
  1105.  
  1106. ;
  1107. ;  HL NOW POINTS TO THE POINTER WHOSE INDEX WAS IN HL TO BEGIN WITH
  1108. ;  DE NOW POINTS TO THE POINTER WHOSE INDEX WAS IN DE TO BEGIN WITH
  1109. ;    FOR EXAMPLE, IF DE=5 AND HL=4, DE NOW POINTS TO THE 5TH PTR AND HL
  1110. ; TO THE 4TH POINTER
  1111. ;
  1112.     MOV    C,M        ; BC IS MADE TO POINT TO THE OBJECT INDEXED TO
  1113.     INX    H        ; ... BY THE ORIGINAL HL
  1114.     MOV    B,M
  1115.     XCHG
  1116.     MOV    E,M        ; DE IS MADE TO POINT TO THE OBJECT INDEXED TO
  1117.     INX    H        ; ... BY THE ORIGINAL DE
  1118.     MOV    D,M
  1119.     MOV    H,B        ; SET HL = OBJECT PTED TO INDIRECTLY BY BC
  1120.     MOV    L,C
  1121.  
  1122. ;
  1123. ;  COMPARE DIR ENTRY PTED TO BY HL WITH THAT PTED TO BY DE;
  1124. ;    NO NET EFFECT ON HL, DE; RET W/CARRY SET MEANS DE<HL
  1125. ;    RET W/ZERO SET MEANS DE=HL
  1126. ;
  1127. CMP$ENTRY:
  1128. ;
  1129. ;  COMPARE BY FILE NAME, FILE TYPE, EXTENSION, AND USER NUM (IN THAT ORDER)
  1130. ;
  1131.     PUSH    H
  1132.     PUSH    D
  1133.     INX    H    ; PT TO FN
  1134.     INX    D
  1135.     MVI    B,11    ; COMPARE FN, FT
  1136.     CALL    COMP
  1137.     POP    D
  1138.     POP    H
  1139.     RNZ
  1140.     LDAX    D    ; COMPARE USER NUMBER
  1141.     CMP    M
  1142.     RET
  1143. ;
  1144. ;  COMP COMPARES DE W/HL FOR B BYTES; RET W/CARRY IF DE<HL
  1145. ;    MSB IS DISREGARDED
  1146. ;
  1147. COMP:
  1148.     MOV    A,M    ; GET (HL)
  1149.     ANI    7FH    ; MASK MSB
  1150.     MOV    C,A    ; ... IN C
  1151.     LDAX    D    ; COMPARE
  1152.     ANI    7FH    ; MASK MSB
  1153.     CMP    C
  1154.     RNZ
  1155.     INX    H    ; PT TO NEXT
  1156.     INX    D
  1157.     DCR    B    ; COUNT DOWN
  1158.     JNZ    COMP
  1159.     RET
  1160. ;
  1161. ;  AS COMP, BUT MATCH ON '?' PTED TO BY HL
  1162. ;
  1163. COMP2:
  1164.     MOV    A,M    ; GET (HL)
  1165.     ANI    7FH    ; MASK MSB
  1166.     CPI    '?'    ; MATCH '?'
  1167.     JZ    COMP2A
  1168.     MOV    C,A    ; ... IN C
  1169.     LDAX    D    ; COMPARE
  1170.     ANI    7FH    ; MASK MSB
  1171.     CMP    C
  1172.     RNZ
  1173. COMP2A:
  1174.     INX    H    ; PT TO NEXT
  1175.     INX    D
  1176.     DCR    B    ; COUNT DOWN
  1177.     JNZ    COMP2
  1178.     RET
  1179.  
  1180. ;
  1181. ;  SORT BUFFERS
  1182. ;
  1183. ORDER:
  1184.     DS    2    ; PTR TO ORDER TABLE
  1185. DIRBUF:
  1186.     DS    2    ; POINTER TO DIRECTORY
  1187. DSTART:
  1188.     DS    2    ; POINTER TO FIRST DIRECTORY ENTRY
  1189. FCOUNT:
  1190.     DS    2    ; TOTAL NUMBER OF FILES/NUMBER OF SELECTED FILES
  1191. HOLD:
  1192.     DS    ESIZE    ; EXCHANGE HOLD BUFFER FOR FCB'S
  1193. PTPTR:
  1194.     DS    2    ; POINTER POINTER
  1195. PTDIR:
  1196.     DS    2    ; DIRECTORY POINTER
  1197. I:
  1198.     DS    2    ; INDEXES FOR SORT
  1199. J:
  1200.     DS    2
  1201. JG:
  1202.     DS    2
  1203. N:
  1204.     DS    2    ; NUMBER OF ELEMENTS TO SORT
  1205. GAP:
  1206.     DS    2    ; BINARY GAP SIZE
  1207. ;
  1208. ; THIS IS THE WORKING COPY OF THE BIOS JUMP TABLE
  1209. ;
  1210. WBOOT:     DS    3
  1211. CONST:     DS    3
  1212. CONIN:     DS    3
  1213. CONOUT:     DS    3
  1214. LIST:     DS    3
  1215. PUNCH:     DS    3
  1216. READER:     DS    3
  1217. HOME:     DS    3
  1218. SELDSK:     DS    3
  1219. SETTRK:     DS    3
  1220. SETSEC:     DS    3
  1221. SETDMA:     DS      3
  1222. READ:     DS    3
  1223. WRITE:     DS    3
  1224. LISTST:     DS    3
  1225. SECTRAN: DS    3
  1226. ;
  1227.      DS    100        ;STACK DEPTH
  1228. STACK:
  1229.     DS    2        ;LOCATION OF STACK
  1230. ;
  1231. ; DATA AREAS
  1232. ;
  1233. FNCOUNT:
  1234.     DS    1        ;NUMBER OF FILE NAMES FOUND
  1235. CLPFLG:    DS    1        ;0 FOR NO MATCH LOCALLY
  1236. SYSTEM:    DS    1        ;0 IF NO SYSTEM FILES
  1237. ECOUNT:    DS    1        ;COUNT OF ENTRIES PRINTED - 1
  1238. FFLAG:    DS    1        ;FILE FOUND FLAG (0=NO)
  1239. TEMP:    DS    2        ;TEMP STORAGE FOR FCB PRINT
  1240. ;
  1241. ;  DISK PARAMETER DATA
  1242. ;
  1243. DPH:    DS    2        ;ADDRESS OF DPH
  1244. DIRMAX:    DS    2        ;NUMBER OF SECTORS IN DIRECTORY =
  1245. ;                ;   MAXIMUM NUMBER OF DIRECTORY ENTRIES
  1246. ;                ;   DIVIDED BY 4 (ENTRIES PER SECTOR)
  1247. EXTENT:    DS    1        ;EXTENT MASK
  1248. MAXSEC:    DS    2        ;MAXIMUM NUMBER OF SECTORS/TRACK
  1249. SECTOR:    DS    2        ;CURRENT SECTOR NUMBER
  1250. TRACK:    DS    2        ;TRACK NUMBER OF DIRECTORY
  1251.  
  1252. FNTAB:    DS    11*40        ;ARBITRARILY LARGE
  1253.  
  1254. SCRATCH    EQU    $/100H*100H+100H    ;BEGINNING OF NEXT PAGE
  1255.  
  1256.     END
  1257.