home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ZSYS / SIMTEL20 / SYSLIB / SLIB1.LBR / SDIRQ.Z80 < prev    next >
Text File  |  2000-06-30  |  18KB  |  706 lines

  1. ;
  2. ; SYSLIB Module Name:  SDIRQ
  3. ; Author:  Richard Conn
  4. ; Part of SYSLIB3 SDIR Series
  5. ; SYSLIB Version Number:  3.6
  6. ; Module Version Number:  1.5
  7.  
  8.     public    dirq
  9.  
  10. ;
  11. ; EQUATES
  12. ;
  13. CPM    EQU    0
  14. BDOS    EQU    5
  15. BUFF    EQU    80H    ; DMA BUFFER
  16. ESIZE    EQU    16    ; 16 BYTES/ENTRY
  17.  
  18. ;
  19. ;  GENERAL-PURPOSE DIRECTORY SELECT ROUTINE WITHOUT SIZING INFORMATION
  20. ;    THIS ROUTINE SCANS FOR THE FCB PTED TO BY DE AND LOADS ALL ENTRIES
  21. ; WHICH MATCH IT INTO THE MEMORY BUFFER PTED TO BY HL.  ON EXIT, 
  22. ; BC=NUMBER OF FILES IN BUFFER, AND HL PTS TO FIRST FILE IN BUFFER.
  23. ;    THE DIRECTORY BUFFER GENERATED BY DIRQ CONTAINS ENTRIES WHICH MAY NOT
  24. ; BE USED TO COMPUTE THE SIZE OF THE FILES USING THE FSIZE ROUTINE.  THE
  25. ; DIRQS ROUTINE IS DESIGNED FOR THIS PURPOSE.  THE BASIC TRADEOFF BETWEEN
  26. ; THE TWO ROUTINES IS THE DIRQ RUNS FASTER THAN DIRQS, AND THIS IS NOTICABLE
  27. ; IF THERE IS A SIGNIFICANT NUMBER OF FILES TO BE PROCESSED.
  28. ;
  29. ;    THE DIRQ/DIRQS ROUTINES ARE INTENDED TO BE USED IN APPLICATIONS WHERE
  30. ; THE ONLY THING DESIRED IS A DIRECTORY LOAD OF THE CURRENT DIRECTORY
  31. ; (DISK AND USER).  DIRF/DIRFS PROVIDE MORE FLEXIBILITY AT A GREATER COST
  32. ; IN TERMS OF SIZE.
  33. ;
  34. ;    INPUT PARAMETERS:
  35. ;    HL PTS TO BUFFER, DE PTS TO FCB, A IS SELECT FLAG:
  36. ;            Bit 7 - Select Non-Sys, Bit 6 - Select Sys
  37. ;            Bit 5 - Sort by File Name and Type (0) or other (1)
  38. ;            Bits 4-0 - Unused
  39. ;    OUTPUT PARAMETERS:
  40. ;    HL PTS TO FIRST FILE IN BUFFER
  41. ;    BC = NUMBER OF FILES
  42. ;    A=0 and Z Flag Set if TPA Overflow
  43. ;    DE UNCHANGED
  44. ;
  45. DIRQ:
  46.     PUSH    DE    ; SAVE PTR TO FCB
  47.  
  48.     LD    (SELFLG),A    ; SAVE SELECT FLAG FOR SELECTION AND ALPHA
  49.     LD    (HOLD),HL    ; SET PTR TO HOLD BUFFER
  50.     LD    BC,36    ; ALLOW 36 BYTES
  51.     ADD    HL,BC    ; HL NOW POINTS TO TEMP FCB
  52.     LD    (TFCB),HL    ; SET PTR TO TEMP FCB
  53.     ADD    HL,DE    ; HL NOW PTS TO SCRATCH AREA
  54.  
  55.     PUSH    DE    ; SAVE PTR TO FCB
  56.     CALL    DBUFFER    ; GET PTRS
  57.     POP    DE    ; GET PTR TO FCB
  58.     PUSH    HL    ; SAVE PTR TO BUFFER
  59.     CALL    DIRLOAD    ; LOAD DIRECTORY WITHOUT SIZING INFORMATION (FAST LOAD)
  60.     POP    HL    ; GET PTR TO BUFFER
  61.  
  62.     POP    DE    ; GET PTR TO FCB
  63.  
  64.     RET    Z        ; ABORT IF TPA OVERFLOW
  65.  
  66.     PUSH    AF    ; SAVE FLAG TO INDICATE NO TPA OVERFLOW
  67.     CALL    DIRALPHA    ; ALPHABETIZE
  68.     POP    AF    ; GET PSW (TPA OVERFLOW FLAG)
  69.     RET
  70.  
  71. ;
  72. ;  THIS ROUTINE ACCEPTS A BASE ADDRESS FOR THE DYNAMIC BUFFERS
  73. ;    REQUIRED, DETERMINES HOW MUCH SPACE IS REQUIRED FOR THE BUFFERS,
  74. ;    AND SETS THE ORDER PTR TO PT TO THE FIRST AND DIRBUF TO PT TO
  75. ;    THE SECOND (ORDER SPACE = DIRMAX*2 AND DIRBUF = DIRMAX * ESIZE)
  76. ;  ON INPUT, HL PTS TO AVAILABLE BASE
  77. ;  ON OUTPUT, HL PTS TO DIRBUF
  78. ;    A=0 AND ZERO FLAG SET IF CCP OVERRUN
  79. ;
  80. DBUFFER:
  81.     LD    (ORDER),HL    ; PT TO ORDER TABLE
  82.     CALL    DPARAMS    ; GET PARAMETERS
  83.     LD    HL,(DIRMAX)    ; NUMBER OF ENTRIES IN DIR
  84.     EX    DE,HL        ; ... IN DE
  85.     LD    HL,(ORDER)    ; ADD TO ORDER BASE
  86.     ADD    HL,DE    ; *1
  87.     CALL    MEMCHK    ; CHECK FOR WITHIN RANGE
  88.     ADD    HL,DE    ; HL PTS TO DIRBUF
  89.     CALL    MEMCHK    ; CHECK FOR WITHIN RANGE
  90.     LD    (DIRBUF),HL    ; SET PTR AND HL PTS TO DIRECTORY BUFFER
  91.     XOR    A    ; OK
  92.     DEC    A    ; SET FLAGS (NZ)
  93.     RET
  94.  
  95. MEMCHK:
  96.     PUSH    HL    ; SAVE REGS
  97.     PUSH    DE
  98.     EX    DE,HL        ; NEXT ADDRESS IN DE
  99.     LD    HL,(BDOS+1)    ; GET ADDRESS OF BDOS
  100.     LD    A,D    ; CHECK FOR PAGE OVERRUN
  101.     CP    H
  102.     JP    NC,MEMORUN    ; OVERRUN IF D>=H
  103.     POP    DE
  104.     POP    HL
  105.     RET
  106. MEMORUN:
  107.     POP    DE    ; RESTORE
  108.     POP    HL
  109.     POP    AF    ; CLEAR STACK
  110.     XOR    A    ; RETURN 0
  111.     RET
  112.  
  113. ;
  114. ;  THIS ROUTINE EXTRACTS DISK PARAMETER INFORMATON FROM THE DPB AND
  115. ;    STORES THIS INFORMATION IN:
  116. ;    BLKSHF    <-- BLOCK SHIFT FACTOR (1 BYTE)
  117. ;    BLKMSK    <-- BLOCK MASK (1 BYTE)
  118. ;    EXTENT  <-- EXTENT MASK (1 BYTE) [NOT ANY MORE]
  119. ;    BLKMAX    <-- MAX NUMBER OF BLOCKS ON DISK (2 BYTES)
  120. ;    DIRMAX    <-- MAX NUMBER OF DIRECTORY ENTRIES (2 BYTES)
  121. ;
  122. DPARAMS:
  123. ;
  124. ;  VERSION 2.x OR MP/M
  125. ;
  126.     LD    C,31    ; 2.x OR MP/M...REQUEST DPB
  127.     CALL    BDOS
  128.     INC    HL
  129.     INC    HL
  130.     LD    A,(HL)    ; GET BLOCK SHIFT
  131.     LD    (BLKSHF),A    ; BLOCK SHIFT FACTOR
  132.     INC    HL    ; GET BLOCK MASK
  133.     LD    A,(HL)
  134.     LD    (BLKMSK),A    ; BLOCK MASK
  135.     INC    HL
  136.     INC    HL
  137.     LD    E,(HL)    ; GET MAX BLOCK NUMBER
  138.     INC    HL
  139.     LD    D,(HL)
  140.     EX    DE,HL
  141.     INC    HL    ; ADD 1 FOR MAX NUMBER OF BLOCKS
  142.     LD    (BLKMAX),HL    ; MAXIMUM NUMBER OF BLOCKS
  143.     EX    DE,HL
  144.     INC    HL
  145.     LD    E,(HL)    ; GET DIRECTORY SIZE
  146.     INC    HL
  147.     LD    D,(HL)
  148.     EX    DE,HL
  149.     INC    HL    ; ADD 1 FOR NUMBER OF ENTRIES
  150.     LD    (DIRMAX),HL    ; MAXIMUM NUMBER OF DIRECTORY ENTRIES
  151.     RET
  152.  
  153. ;
  154. ;  BUILD DIRECTORY TABLE AT DIRBUF
  155. ;    THIS IS THE OPTIMAL DIRECTORY LOAD ROUTINE; IT ONLY LOADS UNIQUE
  156. ;        FILE NAMES FROM DISK, BUT THE INFORMATION IS NOT SUFFICIENT
  157. ;        TO COMPUTE THE FILE SIZES
  158. ;    ON INPUT, HL PTS TO DIRECTORY BUFFER (16 x N MAX)
  159. ;        DE PTS TO FCB (ONLY 12 BYTES NEEDED)
  160. ;    ON OUTPUT, BC IS NUM OF FILES
  161. ;        A=0 AND ZERO FLAG SET IF TPA OVERFLOW
  162. ;
  163. DIRLOAD:
  164.     INC    DE    ; PT TO FILE NAME
  165.     LD    HL,(TFCB)    ; PT TO TFCB
  166.     LD    (HL),0    ; SELECT CURRENT DISK
  167.     INC    HL    ; PT TO FILE NAME IN TFCB
  168.     LD    B,11    ; 11 CHARS
  169. DLLOOP:
  170.     LD    A,(DE)    ; COPY
  171.     LD    (HL),A
  172.     INC    HL    ; PT TO NEXT
  173.     INC    DE
  174.     DEC    B    ; COUNT DOWN
  175.     JP    NZ,DLLOOP
  176.     LD    B,24    ; 24 CHARS (INCL ZERO EX)
  177.     XOR    A    ; ZERO REST OF TFCB
  178. DLLOOP1:
  179.     LD    (HL),A    ; STORE ZERO
  180.     INC    HL    ; PT TO NEXT
  181.     DEC    B    ; COUNT DOWN
  182.     JP    NZ,DLLOOP1
  183.  
  184. ;
  185. ;  THIS SECTION OF CODE INITIALIZES THE COUNTERS USED
  186. ;
  187.     LD    HL,0    ; HL=0
  188.     LD    (FCOUNT),HL    ; TOTAL FILES ON DISK = 0
  189. ;
  190. ;  NOW WE BEGIN SCANNING FOR FILES TO PLACE INTO THE MEMORY BUFFER
  191. ;
  192.     LD    C,17    ; SEARCH FOR FILE
  193.     JP    DIRLP1
  194. DIRLP:
  195.     CALL    PENTRY    ; PLACE ENTRY IN DIR
  196.     JP    Z,DIROVFL    ; MEMORY OVERFLOW ERROR
  197.     LD    C,18    ; SEARCH FOR NEXT MATCH
  198. DIRLP1:
  199.     LD    HL,(TFCB)    ; PT TO FCB
  200.     EX    DE,HL
  201.     CALL    BDOS
  202.     CP    255    ; DONE?
  203.     JP    NZ,DIRLP
  204. ;
  205. ;  NOW WE ARE DONE WITH THE LOAD -- SET UP RETURN VALUES
  206. ;
  207. DIRDN:
  208.     XOR    A    ; LOAD OK
  209.     DEC    A    ; SET FLAGS (NZ)
  210. DIRDNX:
  211.     LD    HL,(FCOUNT)    ; GET TOTAL NUMBER OF FILES
  212.     LD    B,H    ; ... IN BC
  213.     LD    C,L
  214.     RET
  215. ;
  216. ;  MEMORY OVERFLOW ERROR
  217. ;
  218. DIROVFL:
  219.     XOR    A    ; LOAD ERROR
  220.     JP    DIRDNX
  221.  
  222. ;
  223. ;  PENTRY --
  224. ;  PLACE ENTRY IN DIRECTORY BUFFER IF NOT AN ERASED ENTRY
  225. ;
  226. ;  ON INPUT,  A=0-3 FOR ADR INDEX IN BUFF OF ENTRY FCB
  227. ;          FCOUNT=NUMBER OF FILES IN DIR SO FAR
  228. ;  ON OUTPUT, FCOUNT=NUMBER OF FILES IN DIR SO FAR
  229. ;          A=0 AND ZERO FLAG SET IF MEMORY OVERFLOW ERROR
  230. ;
  231. PENTRY:
  232.     RRCA        ; MULTIPLY BY 32 FOR OFFSET COMPUTATION
  233.     RRCA
  234.     RRCA
  235.     AND    60H    ; A=BYTE OFFSET
  236.     LD    DE,BUFF    ; PT TO BUFFER ENTRY
  237.     LD    L,A    ; LET HL=OFFSET
  238.     LD    H,0
  239.     ADD    HL,DE    ; HL=PTR TO FCB
  240. ;
  241. ;  HL=ADR OF FCB IN BUFF
  242. ;
  243.     CALL    ATTEST    ; TEST ATTRIBUTES
  244.     JP    Z,PEDONE    ; SKIP IF ATTRIBUTE NOT DESIRED
  245.  
  246. ;
  247. ;  COPY FCB PTED TO BY HL INTO DIRECTORY BUFFER
  248. ;
  249.     EX    DE,HL        ; SAVE PTR IN DE
  250.     LD    HL,(DIRBUF)    ; PT TO NEXT ENTRY LOCATION
  251.     EX    DE,HL        ; HL PTS TO FCB, DE PTS TO NEXT ENTRY LOCATION
  252.     LD    B,ESIZE    ; NUMBER OF BYTES/ENTRY
  253.     CALL    SDMOVE    ; COPY FCB INTO MEMORY BUFFER
  254.     EX    DE,HL        ; HL PTS TO NEXT ENTRY
  255.     LD    (DIRBUF),HL    ; SET PTR
  256.     EX    DE,HL        ; PTR TO NEXT ENTRY IN DE
  257.     LD    HL,(BDOS+1)    ; BASE ADDRESS OF BDOS IN HL
  258.     LD    A,H    ; GET BASE PAGE OF BDOS
  259.     SUB    9    ; COMPUTE 1 PAGE IN FRONT OF BASE PAGE OF CCP
  260.     CP    D    ; IS PTR TO NEXT ENTRY BEYOND THIS?
  261.     RET    Z
  262.  
  263. ;  INCREMENT TOTAL NUMBER OF FILES
  264.     LD    HL,(FCOUNT)    ; TOTAL FILES = TOTAL FILES + 1
  265.     INC    HL
  266.     LD    (FCOUNT),HL
  267.  
  268. ;  DONE WITH PENTRY AND NO ERROR
  269. PEDONE:
  270.     XOR    A    ; NO ERROR
  271.     DEC    A    ; SET FLAGS (NZ)
  272.     RET
  273.  
  274. ;
  275. ;  CHECK ATTRIBUTES OF FILE ENTRY PTED TO BY HL AGAINST SELFLG
  276. ;    IF SYSTEM FILE AND SYSTEM ATTRIBUTE SET, RETURN NZ
  277. ;    IF NORMAL FILE AND NORMAL ATTRIBUTE SET, RETURN NZ
  278. ;
  279. ATTEST:
  280.     PUSH    HL    ; SAVE PTR
  281.     LD    BC,10    ; PT TO SYSTEM ATTRIBUTE
  282.     ADD    HL,BC
  283.     LD    A,(HL)    ; GET SYSTEM ATTRIBUTE
  284.     POP    HL    ; RESTORE PTR
  285.     AND    80H    ; CHECK FOR SYS
  286.     LD    A,(SELFLG)    ; GET SELECTION FLAG
  287.     JP    Z,ATDIR
  288.     AND    01000000B    ; CHECK SYSTEM ATTRIBUTE
  289.     RET
  290. ATDIR:
  291.     AND    10000000B    ; CHECK NORMAL ATTRIBUTE
  292.     RET
  293.  
  294. ;
  295. ;  DIRALPHA -- ALPHABETIZES DIRECTORY PTED TO BY HL; BC CONTAINS
  296. ;    THE NUMBER OF FILES IN THE DIRECTORY AND A = SORT FLAG
  297. ;    (0=SORT BY FILE NAME/TYPE, <>0 = SORT BY FILE TYPE/NAME)
  298. ;
  299. DIRALPHA:
  300.     LD    A,B    ; ANY FILES?
  301.     OR    C
  302.     RET    Z
  303.     PUSH    HL    ; SAVE REGS
  304.     PUSH    DE
  305.     PUSH    BC
  306.     LD    (DIRBUF),HL    ; SAVE PTR TO DIRECTORY
  307.     PUSH    HL    ; SAVE HL
  308.     LD    H,B    ; HL=BC=FILE COUNT
  309.     LD    L,C
  310.     LD    (N),HL    ; SET "N"
  311.     POP    HL
  312. ;
  313. ;  SHELL SORT --
  314. ;    THIS SORT ROUTINE IS ADAPTED FROM "SOFTWARE TOOLS"
  315. ;    BY KERNIGAN AND PLAUGHER, PAGE 106.  COPYRIGHT, 1976, ADDISON-WESLEY.
  316. ;  ON ENTRY, BC=NUMBER OF ENTRIES
  317. ;
  318. SORT:
  319.     EX    DE,HL        ; POINTER TO DIRECTORY IN DE
  320.     LD    HL,(ORDER)    ; PT TO ORDER TABLE
  321. ;
  322. ;  SET UP ORDER TABLE; HL PTS TO NEXT ENTRY IN ORDER TABLE, DE PTS TO NEXT
  323. ;    ENTRY IN DIRECTORY, BC = NUMBER OF ELEMENTS REMAINING
  324. ;
  325. SORT1:
  326.     LD    (HL),E    ; STORE LOW-ORDER ADDRESS
  327.     INC    HL    ; PT TO NEXT ORDER BYTE
  328.     LD    (HL),D    ; STORE HIGH-ORDER ADDRESS
  329.     INC    HL    ; PT TO NEXT ORDER ENTRY
  330.     PUSH    HL    ; SAVE PTR
  331.     LD    HL,ESIZE    ; HL=NUMBER OF BYTES/ENTRY
  332.     ADD    HL,DE    ; PT TO NEXT DIR1 ENTRY
  333.     EX    DE,HL        ; DE PTS TO NEXT ENTRY
  334.     POP    HL    ; GET PTR TO ORDER TABLE
  335.     DEC    BC    ; COUNT DOWN
  336.     LD    A,B    ; DONE?
  337.     OR    C
  338.     JP    NZ,SORT1
  339. ;
  340. ;  THIS IS THE MAIN SORT LOOP FOR THE SHELL SORT IN "SOFTWARE TOOLS" BY K&P
  341. ;
  342.  
  343. ;
  344. ;  SHELL SORT FROM "SOFTWARE TOOLS" BY KERNINGHAN AND PLAUGER
  345. ;
  346.     LD    HL,(N)    ; NUMBER OF ITEMS TO SORT
  347.     LD    (GAP),HL    ; SET INITIAL GAP TO N FOR FIRST DIVISION BY 2
  348.  
  349. ;  FOR (GAP = N/2; GAP > 0; GAP = GAP/2)
  350. SRTL0:
  351.     OR    A    ; CLEAR CARRY
  352.     LD    HL,(GAP)    ; GET PREVIOUS GAP
  353.     LD    A,H    ; ROTATE RIGHT TO DIVIDE BY 2
  354.     RRA
  355.     LD    H,A
  356.     LD    A,L
  357.     RRA
  358.     LD    L,A
  359.  
  360. ;  TEST FOR ZERO
  361.     OR    H
  362.     JP    Z,SDONE    ; DONE WITH SORT IF GAP = 0
  363.  
  364.     LD    (GAP),HL    ; SET VALUE OF GAP
  365.     LD    (IVAL),HL    ; SET I=GAP FOR FOLLOWING LOOP
  366.  
  367. ;  FOR (I = GAP + 1; I <= N; I = I + 1)
  368. SRTL1:
  369.     LD    HL,(IVAL)    ; ADD 1 TO I
  370.     INC    HL
  371.     LD    (IVAL),HL
  372.  
  373. ;  TEST FOR I <= N
  374.     EX    DE,HL        ; I IS IN DE
  375.     LD    HL,(N)    ; GET N
  376.     LD    A,L    ; COMPARE BY SUBTRACTION
  377.     SUB    E
  378.     LD    A,H
  379.     SBC    A,D    ; CARRY SET MEANS I > N
  380.     JP    C,SRTL0    ; DON'T DO FOR LOOP IF I > N
  381.  
  382.     LD    HL,(IVAL)    ; SET J = I FOR FIRST SUBTRACTION OF GAP
  383.     LD    (J),HL
  384.  
  385. ;  FOR (J = I - GAP; J > 0; J = J - GAP)
  386. SRTL2:
  387.     LD    HL,(GAP)    ; GET GAP
  388.     EX    DE,HL        ; ... IN DE
  389.     LD    HL,(J)    ; GET J
  390.     LD    A,L    ; COMPUTE J - GAP
  391.     SUB    E
  392.     LD    L,A
  393.     LD    A,H
  394.     SBC    A,D
  395.     LD    H,A
  396.     LD    (J),HL    ; J = J - GAP
  397.     JP    C,SRTL1    ; IF CARRY FROM SUBTRACTIONS, J < 0 AND ABORT
  398.     LD    A,H    ; J=0?
  399.     OR    L
  400.     JP    Z,SRTL1    ; IF ZERO, J=0 AND ABORT
  401.  
  402. ;  SET JG = J + GAP
  403.     EX    DE,HL        ; J IN DE
  404.     LD    HL,(GAP)    ; GET GAP
  405.     ADD    HL,DE    ; J + GAP
  406.     LD    (JG),HL    ; JG = J + GAP
  407.  
  408. ;  IF (V(J) <= V(JG))
  409.     CALL    ICOMPARE    ; J IN DE, JG IN HL
  410.  
  411. ;  ... THEN BREAK
  412.     JP    C,SRTL1
  413.  
  414. ;  ... ELSE EXCHANGE
  415.     LD    HL,(J)    ; SWAP J, JG
  416.     EX    DE,HL
  417.     LD    HL,(JG)
  418.     CALL    ISWAP    ; J IN DE, JG IN HL
  419.  
  420. ;  END OF INNER-MOST FOR LOOP
  421.     JP    SRTL2
  422.  
  423. ;
  424. ;  SORT IS DONE -- RESTRUCTURE DIR1 IN SORTED ORDER IN PLACE
  425. ;
  426. SDONE:
  427.     LD    HL,(N)    ; NUMBER OF ENTRIES
  428.     LD    B,H    ; ... IN BC
  429.     LD    C,L
  430.     LD    HL,(ORDER)    ; PTR TO ORDERED POINTER TABLE
  431.     LD    (PTPTR),HL    ; SET PTR PTR
  432.     LD    HL,(DIRBUF)    ; PTR TO UNORDERED DIRECTORY
  433.     LD    (PTDIR),HL    ; SET PTR DIR BUFFER
  434.  
  435. ;  FIND PTR TO NEXT DIR1 ENTRY
  436. SRTDN:
  437.     LD    HL,(PTPTR)    ; PT TO REMAINING POINTERS
  438.     EX    DE,HL        ; ... IN DE
  439.     LD    HL,(PTDIR)    ; HL PTS TO NEXT DIR ENTRY
  440.     PUSH    BC    ; SAVE COUNT OF REMAINING ENTRIES
  441.  
  442. ;  FIND PTR TABLE ENTRY
  443. SRTDN1:
  444.     LD    A,(DE)    ; GET CURRENT POINTER TABLE ENTRY VALUE
  445.     INC    DE    ; PT TO HIGH-ORDER POINTER BYTE
  446.     CP    L    ; COMPARE AGAINST DIR1 ADDRESS LOW
  447.     JP    NZ,SRTDN2    ; NOT FOUND YET
  448.     LD    A,(DE)    ; LOW-ORDER BYTES MATCH -- GET HIGH-ORDER POINTER BYTE
  449.     CP    H    ; COMPARE AGAINST DIR1 ADDRESS HIGH
  450.     JP    Z,SRTDN3    ; MATCH FOUND
  451. SRTDN2:
  452.     INC    DE    ; PT TO NEXT PTR TABLE ENTRY
  453.     DEC    BC    ; COUNT DOWN
  454.     LD    A,C    ; END OF TABLE?
  455.     OR    B
  456.     JP    NZ,SRTDN1    ; CONTINUE IF NOT
  457.  
  458. ;  FATAL ERROR -- INTERNAL ERROR; POINTER TABLE NOT CONSISTENT
  459. FERR$PTR:
  460.     LD    E,7    ; RING BELL
  461.     LD    C,2    ; OUTPUT
  462.     CALL    BDOS
  463.     JP    CPM
  464.  
  465. ;  FOUND THE POINTER TABLE ENTRY WHICH POINTS TO THE NEXT UNORDERED DIR1 ENTRY
  466. ;    MAKE BOTH POINTERS (PTR TO NEXT, PTR TO CURRENT UNORDERED DIR1 ENTRY)
  467. ;    POINT TO SAME LOCATION (PTR TO NEXT DIR1 ENTRY TO BE ORDERED)
  468. SRTDN3:
  469.     LD    HL,(PTPTR)    ; GET PTR TO NEXT ORDERED ENTRY
  470.     DEC    DE    ; DE PTS TO LOW-ORDER POINTER ADDRESS
  471.     LD    A,(HL)    ; MAKE PTR TO NEXT UNORDERED DIR1 PT TO BUFFER FOR
  472.     LD    (DE),A    ;   DIR1 ENTRY TO BE MOVED TO NEXT UNORDERED DIR1 POS
  473.     INC    HL    ; PT TO NEXT PTR ADDRESS
  474.     INC    DE
  475.     LD    A,(HL)    ; MAKE HIGH POINT SIMILARLY
  476.     LD    (DE),A
  477.  
  478. ;  COPY NEXT UNORDERED DIR1 ENTRY TO HOLD BUFFER
  479.     LD    B,ESIZE    ; B=NUMBER OF BYTES/ENTRY
  480.     LD    HL,(HOLD)    ; PT TO HOLD BUFFER
  481.     EX    DE,HL
  482.     LD    HL,(PTDIR)    ; PT TO ENTRY
  483.     PUSH    BC    ; SAVE B=NUMBER OF BYTES/ENTRY
  484.     CALL    SDMOVE
  485.     POP    BC
  486.  
  487. ;  COPY TO-BE-ORDERED DIR1 ENTRY TO NEXT ORDERED DIR1 POSITION
  488.     LD    HL,(PTPTR)    ; POINT TO ITS POINTER
  489.     LD    E,(HL)    ; GET LOW-ADDRESS POINTER
  490.     INC    HL
  491.     LD    D,(HL)    ; GET HIGH-ADDRESS POINTER
  492.     LD    HL,(PTDIR)    ; DESTINATION ADDRESS FOR NEXT ORDERED ENTRY
  493.     EX    DE,HL        ; HL PTS TO ENTRY TO BE MOVED, DE PTS TO DEST
  494.     PUSH    BC    ; SAVE B=NUMBER OF BYTES/ENTRY
  495.     CALL    SDMOVE
  496.     POP    BC
  497.     EX    DE,HL        ; HL PTS TO NEXT UNORDERED DIR1 ENTRY
  498.     LD    (PTDIR),HL    ; SET POINTER FOR NEXT LOOP
  499.  
  500. ;  COPY ENTRY IN HOLD BUFFER TO LOC PREVIOUSLY HELD BY LATEST ORDERED ENTRY
  501.     LD    HL,(PTPTR)    ; GET PTR TO PTR TO THE DESTINATION
  502.     LD    E,(HL)    ; GET LOW-ADDRESS POINTER
  503.     INC    HL
  504.     LD    D,(HL)    ; HIGH-ADDRESS POINTER
  505.     LD    HL,(HOLD)    ; HL PTS TO HOLD BUFFER, DE PTS TO ENTRY DEST
  506.     CALL    SDMOVE    ; B=NUMBER OF BYTES/ENTRY
  507.  
  508. ;  POINT TO NEXT ENTRY IN POINTER TABLE
  509.     LD    HL,(PTPTR)    ; POINTER TO CURRENT ENTRY
  510.     INC    HL    ; SKIP OVER IT
  511.     INC    HL
  512.     LD    (PTPTR),HL
  513.  
  514. ;  COUNT DOWN
  515.     POP    BC    ; GET COUNTER
  516.     DEC    BC    ; COUNT DOWN
  517.     LD    A,C    ; DONE?
  518.     OR    B
  519.     JP    NZ,SRTDN
  520.     POP    BC    ; RESTORE REGS
  521.     POP    DE
  522.     POP    HL
  523.     RET        ; DONE
  524.  
  525. ;
  526. ;  SWAP (Exchange) the pointers in the ORDER table whose indexes are in
  527. ;    HL and DE
  528. ;
  529. ISWAP:
  530.     PUSH    HL        ; SAVE HL
  531.     LD    HL,(ORDER)        ; ADDRESS OF ORDER TABLE - 2
  532.     LD    B,H        ; ... IN BC
  533.     LD    C,L
  534.     POP    HL
  535.     DEC    HL        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  536.     ADD    HL,HL        ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX
  537.                 ;   OF ORIGINAL HL (1, 2, ...)
  538.     ADD    HL,BC        ; HL NOW PTS TO POINTER INVOLVED
  539.     EX    DE,HL            ; DE NOW PTS TO POINTER INDEXED BY HL
  540.     DEC    HL        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  541.     ADD    HL,HL        ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX
  542.                 ;   OF ORIGINAL DE (1, 2, ...)
  543.     ADD    HL,BC        ; HL NOW PTS TO POINTER INVOLVED
  544.     LD    C,(HL)        ; EXCHANGE POINTERS -- GET OLD (DE)
  545.     LD    A,(DE)        ; -- GET OLD (HL)
  546.     EX    DE,HL            ; SWITCH
  547.     LD    (HL),C        ; PUT NEW (HL)
  548.     LD    (DE),A        ; PUT NEW (DE)
  549.     INC    HL        ; PT TO NEXT BYTE OF POINTER
  550.     INC    DE
  551.     LD    C,(HL)        ; GET OLD (HL)
  552.     LD    A,(DE)        ; GET OLD (DE)
  553.     EX    DE,HL            ; SWITCH
  554.     LD    (HL),C        ; PUT NEW (DE)
  555.     LD    (DE),A        ; PUT NEW (HL)
  556.     RET
  557. ;
  558. ;  ICOMPARE compares the entry pointed to by the pointer pointed to by HL
  559. ;    with that pointed to by DE (1st level indirect addressing); on entry,
  560. ;    HL and DE contain the numbers of the elements to compare (1, 2, ...);
  561. ;    on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)),
  562. ;    and Non-Zero and No-Carry means ((DE)) > ((HL))
  563. ;
  564. ICOMPARE:
  565.     PUSH    HL        ; SAVE HL
  566.     LD    HL,(ORDER)        ; ADDRESS OF ORDER - 2
  567.     LD    B,H        ; ... IN BC
  568.     LD    C,L
  569.     POP    HL
  570.     DEC    HL        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  571.     ADD    HL,HL        ; DOUBLE THE ELEMENT NUMBER TO POINT TO THE PTR
  572.     ADD    HL,BC        ; ADD TO THIS THE BASE ADDRESS OF THE PTR TABLE
  573.     EX    DE,HL            ; RESULT IN DE
  574.     DEC    HL        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  575.     ADD    HL,HL        ; DO THE SAME WITH THE ORIGINAL DE
  576.     ADD    HL,BC
  577.     EX    DE,HL
  578.  
  579. ;
  580. ;  HL NOW POINTS TO THE POINTER WHOSE INDEX WAS IN HL TO BEGIN WITH
  581. ;  DE NOW POINTS TO THE POINTER WHOSE INDEX WAS IN DE TO BEGIN WITH
  582. ;    FOR EXAMPLE, IF DE=5 AND HL=4, DE NOW POINTS TO THE 5TH PTR AND HL
  583. ; TO THE 4TH POINTER
  584. ;
  585.     LD    C,(HL)        ; BC IS MADE TO POINT TO THE OBJECT INDEXED TO
  586.     INC    HL        ; ... BY THE ORIGINAL HL
  587.     LD    B,(HL)
  588.     EX    DE,HL
  589.     LD    E,(HL)        ; DE IS MADE TO POINT TO THE OBJECT INDEXED TO
  590.     INC    HL        ; ... BY THE ORIGINAL DE
  591.     LD    D,(HL)
  592.     LD    H,B        ; SET HL = OBJECT PTED TO INDIRECTLY BY BC
  593.     LD    L,C
  594.  
  595. ;
  596. ;  COMPARE DIR ENTRY PTED TO BY HL WITH THAT PTED TO BY DE;
  597. ;    NO NET EFFECT ON HL, DE; RET W/CARRY SET MEANS DE<HL
  598. ;    RET W/ZERO SET MEANS DE=HL
  599. ;
  600. CMP$ENTRY:
  601.     LD    A,(SELFLG)    ; GROUP BY FILE TYPE?
  602.     AND    00100000B
  603.     JP    Z,CMP$FN$FT
  604. ;
  605. ;  COMPARE BY FILE TYPE AND FILE NAME (IN THAT ORDER)
  606. ;
  607.     PUSH    HL
  608.     PUSH    DE
  609.     LD    BC,9    ; PT TO FT (8 BYTES + 1 BYTE FOR USER NUMBER)
  610.     ADD    HL,BC
  611.     EX    DE,HL
  612.     ADD    HL,BC
  613.     EX    DE,HL        ; DE, HL NOW PT TO THEIR FT'S
  614.     LD    B,3    ; 3 BYTES
  615.     CALL    COMP    ; COMPARE FT'S
  616.     POP    DE
  617.     POP    HL
  618.     RET    NZ        ; CONTINUE IF COMPLETE MATCH
  619.     LD    B,8    ; 8 BYTES
  620.     JP    CMP$FT1
  621. ;
  622. ;  COMPARE BY FILE NAME AND FILE TYPE (IN THAT ORDER)
  623. ;
  624. CMP$FN$FT:
  625.     LD    B,11    ; 11 BYTES FOR FN AND FT
  626. CMP$FT1:
  627.     PUSH    HL
  628.     PUSH    DE
  629.     INC    HL    ; PT TO FN
  630.     INC    DE
  631.     CALL    COMP    ; DO COMPARISON
  632.     POP    DE
  633.     POP    HL
  634.     RET
  635. ;
  636. ;  COMP COMPARES DE W/HL FOR B BYTES; RET W/CARRY IF DE<HL
  637. ;    MSB IS DISREGARDED
  638. ;
  639. COMP:
  640.     LD    A,(HL)    ; GET (HL)
  641.     AND    7FH    ; MASK MSB
  642.     LD    C,A    ; ... IN C
  643.     LD    A,(DE)    ; COMPARE
  644.     AND    7FH    ; MASK MSB
  645.     CP    C
  646.     RET    NZ
  647.     INC    HL    ; PT TO NEXT
  648.     INC    DE
  649.     DEC    B    ; COUNT DOWN
  650.     JP    NZ,COMP
  651.     RET
  652.  
  653. ;
  654. ; COPY FROM HL TO DE FOR B BYTES
  655. ;
  656. SDMOVE:
  657.     LD    A,(HL)    ; COPY
  658.     LD    (DE),A
  659.     INC    HL    ; PT TO NEXT
  660.     INC    DE
  661.     DEC    B    ; COUNT DOWN
  662.     JP    NZ,SDMOVE
  663.     RET
  664.  
  665. ;
  666. ;  BUFFERS
  667. ;
  668. HOLD:
  669.     DS    2    ; EXCHANGE HOLD BUFFER FOR FCB'S
  670. PTPTR:
  671.     DS    2    ; POINTER POINTER
  672. PTDIR:
  673.     DS    2    ; DIRECTORY POINTER
  674. IVAL:
  675.     DS    2    ; INDEXES FOR SORT
  676. J:
  677.     DS    2
  678. JG:
  679.     DS    2
  680. N:
  681.     DS    2    ; NUMBER OF ELEMENTS TO SORT
  682. GAP:
  683.     DS    2    ; BINARY GAP SIZE
  684.  
  685. TFCB:
  686.     DS    2    ; ADDRESS OF TEMPORARY FCB
  687. FCOUNT:
  688.     DS    2    ; TOTAL NUMBER OF FILES/NUMBER OF SELECTED FILES
  689.  
  690. BLKSHF:
  691.     DB    0    ; BLOCK SHIFT FACTOR
  692. BLKMSK:
  693.     DB    0    ; BLOCK MASK
  694. BLKMAX:
  695.     DW    0    ; MAX NUMBER OF BLOCKS
  696. DIRMAX:
  697.     DW    0    ; MAX NUMBER OF DIRECTORY ENTRIES
  698. SELFLG:
  699.     DB    0    ; FILE ATTRIBUTE FLAG
  700. ORDER:
  701.     DW    0    ; POINTER TO ORDER TABLE
  702. DIRBUF:
  703.     DW    0    ; POINTER TO DIRECTORY
  704.  
  705.     END
  706.