home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / cpm / utils / f / ql41.ark / QFC.LIB < prev    next >
Encoding:
Text File  |  1990-04-13  |  14.5 KB  |  591 lines

  1. ;; Changes:
  2. ;;  11/12/88:   Added line to re-display if no files selected inside ().
  3. ;;  11/08/88:    Added line at SELALL to print '*' when it's hit.
  4. ;;        Fixed help msg.
  5.  
  6. ;=======================================================================
  7. ; QFC.LIB ; 
  8. ;==========
  9. ;
  10. ; These routines form the choose-by-number interface, which is used 
  11. ; repeatedly.  The entry point is QFC.  A pointer to QFC's parameter block
  12. ; should be passed in register IX.  This is the format of the parameter block.
  13.  
  14. ;FNCNT    DS    1        ; Number of entries in table.
  15. ;FNTBL    DS    2        ; Pointer to the first entry in table.
  16. ;ENTLEN    DS    1        ; Length of an entry.
  17. ;FNOFFS    DS    1        ; Offset of filename from entry start.
  18. ;FNPARS    DS    1        ; YES if filenames are in form fn.typ.
  19.                 ; NO  if filenames are in form fn------typ.
  20. ;FNSORT    DS    1        ; YES to sort before beginning.
  21.                 ; NO  to leave in existing order.
  22. ;FNSELD DS    1        ; Count of files selected.
  23. ;FNMULT    DS    16        ; fn numbers (if multiple selected).
  24. ;HEDRTN DS    2        ; Routine to print screen header.
  25. ;
  26. ; By making these values parameters, it becomes easy to use the same
  27. ; code for choosing a file, an LBR member, or an ARC member.
  28. ;
  29. ; Returned values:
  30. ; HL will point to the start of the [first] entry selected.
  31. ; A will hold the number of that entry.
  32. ; B will hold the count of files selected, or 255 for "all".
  33. ; Z flag is set iff an exit char was pressed.
  34. ; C flag is set iff an unrecognizable char was pressed (so caller can process).
  35. ;   This allows us to handle (E)xtract/(V)iew toggling. 
  36. ; On successive calls to QFC when a multi-selection is active,
  37. ; QFC loads the appropriate values and returns, without redisplaying the screen.
  38. ;
  39. ; The subroutine LOOKUP, which is used by QFC, is also available to
  40. ; the rest of the program.  It takes the entry number in C and returns
  41. ; HL to point to the filename within the entry.
  42. ;
  43. ; Note that for LBR, ARC, or other 'collection' processing, some information
  44. ; bearing on how to find the member ought to be saved along with the entry.
  45. ; For LBR, this is part of the directory entry; for ARC, we store the sector
  46. ; and offset along with the header.
  47. ;=============================================================================
  48. ;...
  49. ; QFC equates
  50.  
  51. QFCBLKSIZ    EQU    26    ; Length of QFC param block
  52. FNCNT        EQU    0    ; Positions of variables within block
  53. FNTBL        EQU    1
  54. ENTLEN        EQU    3
  55. FNOFFS        EQU    4
  56. FNPARS        EQU    5
  57. FNSORT        EQU    6
  58. FNSELD        EQU    7
  59. FNMULT        EQU    8
  60. HEDRTN        EQU    24
  61.  
  62. ;
  63. ; Main entry point.
  64. ;
  65. ; Decide whether to parse and/or sort.
  66.  
  67. QFC:    LD    A,(IX+FNPARS)    ; Should we parse?
  68.     OR    A
  69.     JR    Z,NOPARS
  70.  
  71.     LD    C,1
  72.     CALL    LOOKUP        ; Point to first fn
  73.     LD    E,(IX+ENTLEN)
  74.     LD    D,0        ; DE = entry length
  75.     LD    B,(IX+FNCNT)    ; B = entry count
  76. PARSLP:    CALL    PARSFN        ; Parse next fn
  77.     ADD    HL,DE        ; Point to next
  78.     DJNZ    PARSLP        ; Loop
  79.     LD    (IX+FNPARS),0    ; Reset "must parse" flag
  80.  
  81. NOPARS:    LD    A,(IX+FNSORT)    ; Should we sort?
  82.     OR    A
  83.     JR    Z,SWEEP
  84.  
  85.     LD    H,(IX+FNOFFS)    ; H = sort key start
  86.     LD    L,11        ; L = sort key length
  87.     CALL    SORT        ; Do it
  88.  
  89.     LD    (IX+FNSORT),0    ; Reset "must sort" flag
  90.  
  91. ; See if multi is active.
  92. ;
  93. SWEEP:    LD    A,(IX+FNSELD)    ; Count of files last selected
  94.     OR    A        ; Zero - multi is through.
  95.     JR    Z,SWEEP0
  96.     CP    255        ; 255 - multi is ALL.
  97.     JR    Z,SWPALL
  98.     CP    1        ; One - not multi.
  99.     JR    Z,SWEEP0    ; Otherwise SOME.
  100.  
  101. ; Active multi is SOME.
  102. SWPSOM:    DEC    A        ; One less
  103.     LD    (IX+FNSELD),A
  104.     PUSH    IX        ; Move to HL
  105.     POP    HL
  106.     LD    DE,FNMULT+15    ; Point to end of FNMULT area
  107.     ADD    HL,DE
  108.     LD    BC,0+15*256    ; C=0; B=15
  109. MOVLP:    LD    A,(HL)        ; Get this byte
  110.     LD    (HL),C        ; Save last byte
  111.     LD    C,A        ; Move this to last
  112.     DEC    HL        ; Back up one byte
  113.     DJNZ    MOVLP        ; Loop
  114.                 ; When done, A = first in string
  115.     LD    (HL),A        ; Save it
  116.     JP    GOODFIL        ; Process it
  117.  
  118. ; Active multi is ALL.
  119. SWPALL: LD    A,(IX+FNMULT)    ; Last file processed
  120.     CP    (IX+FNCNT)    ; Was that the last file?
  121.     JR    Z,SWEEP0    ; yes, select something new
  122.  
  123.     INC    A        ; Select next file
  124.     LD    (IX+FNMULT),A    ; Save for next round
  125.     JP    GOODFIL        ; Process this one
  126.  
  127. ; Ready to choose next file to view.
  128. ;
  129. SWEEP0:    XOR    A        ;
  130.     LD    (SCRNUM),A    ; Init "screen#" to zero (goes, 0,72,144..)
  131.     LD    (IX+FNSELD),A    ; Clear multi options    
  132.     JP    NSCR        ; Skip over help msg
  133.  
  134. ;...............................;
  135. ; Help message for QFC.
  136. ;
  137. QFCHLP:    CALL    CLEARSCREEN
  138.     CALL    MSG
  139.     DB    CR,LF,'File selection help:'
  140.     DB    CR,LF
  141.     DB    CR,LF,' ##',TAB,'Select numbered file'
  142.     DB    CR,LF,' <ret>',TAB,'Display next page of files'
  143.     DB    CR,LF,' S',TAB,'Re-sort files starting at nth position'
  144.     DB    CR,LF,TAB,'  (e.g. 8 to sort by extension)'
  145.     DB    CR,LF,' ^C',TAB,'Abort to CP/M'
  146.     DB    CR,LF,' Q',TAB,'Abort to previous level'
  147.     DB    CR,LF
  148.     DB    LF,' *',TAB,'Select ALL files'
  149.     DB    CR,LF,' (#,#)',TAB,'Select SOME files'
  150.     DB    CR,LF
  151.     DB    LF,'Press any key to redisplay files',0
  152. WAITCH:    LD    C,DIRIO        ; wait for a char
  153.     LD    E,0FFH
  154.     CALL    BDOSC1
  155.     OR    A    
  156.     JR    Z,WAITCH    ; Loop until kbhit
  157.     CP    CR        ; Trap CR separately
  158.     JR    Z,NSCR
  159.     CALL    CHEXIT        ; Process 'exit' chars
  160.     JP    Z,QFCEXIT    ; Fall through if no exit
  161. ;...............................;
  162. NSCR:    CALL    HEADER        ; Display proper header:
  163.                 ;   'Files Matching: DU <afn>'
  164.                 ;   'Members of: DU <fn>'
  165.     LD    A,(IX+FNCNT)    ; Count of files
  166.     LD    (HIPG),A    ; Set hipg so can deduce when enuf
  167.     INC    A        ; Count +1
  168.     LD    D,A        ; Max #of files +1 goes into D
  169.  
  170.     LD    E,1        ; E is line#, (init to 1)
  171.  
  172. ;................................
  173.                 ;
  174. LINLP:    LD    B,4        ; Outer loop for NL lines
  175.     LD    A,(SCRNUM)    ;
  176.     ADD    A,E        ; 1st file# in each line = line# + scrn#
  177.     LD    C,A        ;
  178. ;................................
  179.                 ; Inner loop, 4/line
  180. LP4:    LD    A,C        ; File#
  181.     CP    D        ; Compare to max
  182.     JR    NC,OUT4        ; If greater, done w/ this line
  183.     CALL    LOOKUP        ; Convert file # in c to pointer to name in HL
  184.     CALL    PRNUMFN        ; Print xxx:filename.typ
  185.     LD    A,C        ;
  186.     ADD    A,NL        ; Next file, if any, is prev# plus NL
  187.     LD    C,A        ;
  188.     DJNZ    LP4        ;
  189. ;...............................;
  190.  
  191. OUT4:    CALL    CRLF        ;
  192.     LD    A,E        ; Advance to next line
  193.     INC    A        ;
  194.     LD    E,A        ;
  195.     CP    NL+1        ;
  196.     JR    C,LINLP        ;
  197. ;...............................;
  198.  
  199. ; V4.1 all screens now have same msg.
  200.     CALL    MSG
  201.     DB    CR,LF,'File #, cmd, or / for help: ',0
  202.  
  203. BADNUM:
  204.     XOR    A
  205.     LD    (JUMPTO),A    ; Clear jumpto
  206.     CALL    GETCHNUM    ; Get user response
  207.     CALL    UCASE        ; Force upper case
  208.     LD    C,A        ; save char response
  209.     LD    A,(JUMPTO)    ; Did he enter a #?
  210.     OR    A
  211.     JP    NZ,CHKFIL    ; Check it
  212.  
  213.     LD    A,C        ; Get back char
  214.     CP    '/'        ; Asked for help?
  215.     JP    Z,QFCHLP
  216.     CP    '?'
  217.     JP    Z,QFCHLP
  218.     CP    CR        ; Page?
  219.     JR    Z,NXTSCR
  220.     CP    TAB        ; Tab also means page
  221.     JR    Z,NXTSCR
  222.     CP    'S'        ; Sort again?
  223.     JR    Z,RESORT
  224.     CP    '*'        ; All files?
  225.     JR    Z,SELALL
  226.     CP    '('        ; Some files?
  227.     JR    Z,SELSOM
  228. NOCMD:    CALL    CHEXIT        ; ^C, ^K straight to CP/M
  229.     JP    Z,QFCEXIT    ; other exit chars return
  230.     SCF            ; If unrecognized, flag it
  231.     RET            ; and let caller handle it
  232.  
  233. ; Display next screen.
  234. ; Wrap to first screen if at end.
  235. ;
  236. NXTSCR:    LD    A,(SCRNUM)    ; Current "screen #"
  237.     ADD    A,72        ; Plus one screenfull
  238.     JR    C,SCROVF    ; If >255, certainly too big
  239.     CP    (IX+FNCNT)    ; Past end?
  240.     JR    C,NSCROVF    ; If not past end, use this
  241. SCROVF:    SUB    A        ; Point back to beginning
  242. NSCROVF:
  243.     LD    (SCRNUM),A    ; Save new screen#
  244.     JP    NSCR        ; Display it
  245. ;...............................;
  246. ; Re-sort the files.
  247. ; Ask user which char in filename to begin with.
  248. ; This allows sorting by type, name, or any subset thereof.
  249. ;
  250. RESORT:    CALL    MSG
  251.     DB    'Sort files starting at: ',0
  252.     LD    A,10
  253.     LD    (HIPG),A    ; Set hipg
  254.     SUB    A
  255.     LD    (JUMPTO),A    ; Clr jumpto
  256.     CALL    GETCHNUM    ; Get user response
  257.     LD    A,(JUMPTO)
  258.     CP    11        ; Too big?
  259.     JP    NC,NSCR        ; Yep, ignore
  260.     LD    C,A        ; Save
  261.     LD    A,(IX+FNOFFS)    ; Get offset to fn in entry
  262.     ADD    A,C        ; Index into entry
  263.     LD    H,A        ; move to H
  264.     LD    A,11        ; Compute length of sort key
  265.     SUB    C
  266.     LD    L,A        ; Put in L
  267.     CALL    SORT        ; Do the sort
  268.     JP    NSCR        ; Redisplay
  269. ;...............................;
  270. ; Select all files.
  271. ; Set up return variables and return.
  272. SELALL:    CALL    PUTC        ; Print asterisk
  273.     LD    A,255        ; mark for 'ALL'
  274.     LD    (IX+FNSELD),A
  275.     LD    A,1        ; Index to first file
  276.     LD    (IX+FNMULT),A
  277.     LD    L,(IX+FNTBL)
  278.     LD    H,(IX+FNTBL+1)    ; Pointer to first entry
  279.     OR    A        ; Reset Z,C flags
  280.     RET            ; All done
  281. ;...............................;
  282. ; Select 'some' files.
  283. ; Triggered when user types a '('.
  284. ; Get successive file #s until 15 have been chosen,
  285. ; or ')' (or CR) is typed.
  286. SELSOM:    CALL    PUTC        ; Print the (
  287.     LD    B,0        ; Count the files
  288.     LD    HL,FNMULT    ; Place to put them
  289.     PUSH    IX
  290.     POP    DE
  291.     ADD    HL,DE
  292.  
  293. SSLP:    SUB    A        ; Clr JUMPTO
  294.     LD    (JUMPTO),A
  295.     PUSH    BC        ; Save vitals
  296.     PUSH    HL
  297.     CALL    GETCHNUM    ; Get next selection
  298.     POP    HL        ; Restore vitals
  299.     POP    BC
  300.     LD    C,A        ; Save char
  301.     LD    A,(JUMPTO)    ; Get response
  302.     OR    A        ; Zero?
  303.     JR    NZ,SSCHK    ; Check it out if not
  304.     LD    A,C        ; Restore char
  305.     CP    ')'        ; Closed parens?
  306.     JR    Z,SSDON        ; Yes, finish up
  307.     CP    CR        ; <cr> also finishes list
  308.     JR    Z,SSDON        ;
  309.     JR    SSLP        ; Others are ignored
  310.  
  311. SSCHK:    CP    (IX+FNCNT)    ; File # out of range?
  312.     JR    C,SSGOOD    ; <max is ok
  313.     JR    Z,SSGOOD    ; =max is ok
  314.     CALL    UNBDEC        ; Erase from screen
  315.     JR    SSLP        ; Try again
  316.  
  317. SSGOOD:    LD    (HL),A        ; Save it here
  318.     INC    HL        ; bump save ptr
  319.     INC    B        ; Count it here
  320.     LD    A,','        ; delimit char
  321.     CALL    PUTC
  322.     LD    A,B        ; Full yet?
  323.     CP    16
  324.     JR    NZ,SSLP        ; Nope, loop
  325.  
  326. SSDON:    CALL    BACKSP        ; Erase last comma
  327.     LD    A,')'        ; Close paren
  328.     CALL    PUTC
  329.     LD    (HL),0        ; End the sequence
  330.      LD    A,B        ; Load count
  331.     OR    A
  332.     JP    Z,NSCR        ; Redisplay if none selected
  333.     LD    (IX+FNSELD),A    ; Save here
  334.     LD    A,(IX+FNMULT)    ; index to first
  335.     LD    C,A
  336.     CALL    CALC        ; Make ptr to entry start
  337.     OR    A        ; Reset Z,C flags
  338.     RET
  339. ;................................
  340. ; Check entry for single selection
  341.  
  342. CHKFIL:    LD    C,A
  343.     LD    A,(IX+FNCNT)
  344.     CP    C
  345.     LD    A,C
  346.     JR    NC,GOOD
  347.     CALL    UNBDEC    
  348.     JP    BADNUM
  349.  
  350. GOOD:    LD    (IX+FNMULT),A    ; Save file #
  351.     LD    (IX+FNMULT+1),0    ;
  352.     LD    B,1        ; One file selected
  353.     LD    (IX+FNSELD),B    ; Save it
  354. GOODFIL:
  355.     CALL    CALC        ; Point to entry
  356.     OR    A        ; Reset Z,C flags
  357.     RET            ; Return
  358. ;...............................;
  359. ; Exit routine
  360. ; When user hits an 'exit key'
  361.  
  362. QFCEXIT:
  363.     LD    HL,0        ; Point nowhere
  364.     LD    A,L        ; File # = 0
  365.     LD    B,0        ; Files selected=0
  366.     LD    (IX+FNSELD),A    ; No files selected
  367.     LD    (IX+FNMULT),A    ; Index = 0
  368.     OR    A        ; Reset C flag, set Z flag    
  369.     RET            ; With Z flag set
  370. ;...............................;
  371. ; Various subroutines
  372. ;
  373. UNBDEC:    CALL    BELL        ; Beep!
  374.     CP    100        ; 3 digits?
  375.     CALL    NC,BACKSP    ; erase hundreds
  376.     CP    10        ; 2 digits?
  377.     CALL    NC,BACKSP    ; erase tens
  378.                 ; fall through to erase ones
  379. BACKSP:    PUSH    AF
  380.     PUSH    HL
  381.     CALL    MSG
  382.     DB    8,' ',8,0
  383.     POP    HL
  384.     POP    AF
  385.     RET
  386.  
  387. BELL:    PUSH    AF
  388.     LD    A,BEL        ; Beep!
  389.     CALL    PUTC
  390.     POP    AF
  391.     RET
  392.  
  393. HEADER:    PUSH    IX        ; Save IX reg
  394.     LD    HL,HEADRET    ; New return address
  395.     PUSH    HL
  396.     LD    L,(IX+HEDRTN)    ; Load ptr to header routine
  397.     LD    H,(IX+HEDRTN+1)    ;
  398.     JP    (HL)
  399. HEADRET:
  400.     POP    IX        ; Restore IX reg
  401.     RET
  402.  
  403. HEADJP:    JP    (HL)
  404. ;...............................;
  405. ; Lookup fcn
  406. ; Converts C, entry #, into ptr
  407. ; to fn within entry (HL)
  408. ; None destroyed
  409.  
  410. LOOKUP:    PUSH    AF
  411.     PUSH    DE
  412.     LD    A,C
  413.     CALL    CALC
  414.     LD    E,(IX+FNOFFS)
  415.     LD    D,0
  416.     ADD    HL,DE
  417.     POP    DE
  418.     POP    AF
  419.     RET
  420. ;...............................;
  421. ; Calc fcn
  422. ; Converts A, entry #, into ptr
  423. ; to start of entry (HL)
  424. ; None destroyed
  425.  
  426. CALC:    PUSH    DE
  427.     PUSH    AF
  428.     LD    L,(IX+FNTBL)
  429.     LD    H,(IX+FNTBL+1)
  430.     LD    E,(IX+ENTLEN)
  431.     LD    D,0
  432.     DEC    A
  433. CALC0:    SRL    A
  434.     JR    NC,CALC1
  435.     ADD    HL,DE
  436. CALC1:    EX    DE,HL
  437.     ADD    HL,HL
  438.     EX    DE,HL
  439.     OR    A
  440.     JR    NZ,CALC0
  441.     POP    AF
  442.     POP    DE
  443.     RET
  444. ;...............................
  445. ; Parse fcn
  446. ; Takes fn.typ at (HL) and converts
  447. ; to fn------typ at (HL)
  448. ; None destroyed
  449.  
  450. PARSFN:    PUSH    AF        ; Save all
  451.     PUSH    BC
  452.     PUSH    DE
  453.     PUSH    HL
  454.  
  455.     LD    DE,FCB3+1    ; Temporary place to put result
  456.     LD    BC,8        ; 8 chars in first segment
  457. PFN0:    LD    A,(HL)        ; Get next char
  458.     AND    127        ; ASCII mask (no file attributes!)
  459.     JR    Z,PFN1        ; If zero, was end of string char
  460.     CP    '.'        ; Dot yet?
  461.     JR    Z,PFN1
  462.     LDI            ; Transfer char
  463.     JP    PE,PFN0        ; Loop if not done
  464. ; if we get here, the filename may be too long.  We ignore bytes until we find
  465. ; a dot or null.
  466. PFNSKP:    LD    A,(HL)
  467.     OR    A        ; Null?
  468.     JR    Z,PFN2
  469.     CP    '.'        ; Dot?
  470.     JR    Z,PFN2
  471.     INC    HL        ; Test next char
  472.     JR    PFNSKP
  473.  
  474. PFN1:    LD    A,' '        ; Fill remaining part of first segment
  475.     LD    (DE),A        ; With spaces
  476.     INC    DE
  477.     DEC    C
  478.     JR    NZ,PFN1
  479. PFN2:    INC    HL        ; Bump past dot
  480.     LD    BC,3        ; Three more chars
  481.  
  482. PFN2B:    LD    A,(HL)        ; Get char
  483.     OR    A        ; Null means we fill with space
  484.     JR    NZ,PFN4
  485.     LD    A,' '        ; Fill with space
  486. PFN3:    LD    (DE),A
  487.     INC    DE
  488.     DEC    C
  489.     JR    NZ,PFN3
  490.     JR    PFNDON
  491.  
  492. PFN4:    LDI            ; Transfer char
  493.     JP    PE,PFN2B    ; Loop
  494.  
  495. PFNDON:    POP    DE        ; original source again
  496.     PUSH    DE        ; BAck on stack
  497.     LD    HL,FCB3+1    ; Temp area
  498.     LD    BC,11        ; bytes to move
  499.     LDIR
  500.     POP    HL        ; Restore all
  501.     POP    DE
  502.     POP    BC
  503.     POP    AF
  504.     RET
  505. ;..............................................................................
  506. ;
  507. ; Bubble sort all the entries.  Key starts at H and has length L.
  508. ;
  509. SORT:    LD    (80H),HL    ; Save sort key info here (re-use space) 
  510.     LD    A,(IX+FNCNT)    ; #of entries to be sorted
  511.     DEC    A        ; minus 1
  512.     RET    Z        ; Can't sort 1 entry!
  513.     LD    C,A        ; Init outer loop counter
  514.  
  515. ;................................
  516.                 ;
  517. OUTRLP:    LD    B,C        ; Init inner loop counter
  518.     LD    E,(IX+FNTBL)    ; Get table base
  519.     LD    D,(IX+FNTBL+1)    ; (DE) = first entry
  520.     LD    L,(IX+ENTLEN)    ; Get entry length
  521.     LD    H,0        ;
  522.     ADD    HL,DE        ; (HL) = 2nd entry
  523. ;...............................;
  524.                 ;
  525. INRLP:    PUSH    BC        ; Save loop counters
  526.     CALL    COMP        ; Compare two entries
  527.     CALL    C,SWAP        ; Swap if necessary
  528.     LD    C,(IX+ENTLEN)    ; Bump ptrs
  529.     LD    B,0        ;
  530.     ADD    HL,BC        ;
  531.     EX    DE,HL        ;
  532.     ADD    HL,BC        ;
  533.     EX    DE,HL        ;
  534.     POP    BC        ; Restore loop counters
  535.     DJNZ    INRLP        ; End inner loop
  536. ;...............................;
  537.  
  538.     DEC    C        ; End outer loop
  539.     JR    NZ,OUTRLP    ; Loop till done
  540.  
  541.     RET            ;
  542.  
  543. ;..............................................................................
  544. ;
  545. ; Compare the entries at (HL) and (DE) [ Used by SORT above]
  546. ;
  547. COMP:    PUSH    DE        ;
  548.     PUSH    HL        ;
  549.     LD    A,(81h)        ; Retrieve sort key offset
  550.     LD    C,A
  551.     LD    B,0        ;
  552.     ADD    HL,BC        ;
  553.     EX    DE,HL        ; DE -> jth key
  554.     ADD    HL,BC        ; HL -> j+1th key
  555.     LD    A,(80h)        ; Retrieve sort key length
  556.     LD    B,A
  557.  
  558. COMPLP:    LD    A,(DE)        ;
  559.     CP    (HL)        ;
  560.     JR    NZ,CMPRTN    ; If not equal, rtn with appropriate carry stat
  561.     INC    HL        ;
  562.     INC    DE        ;
  563.     DJNZ    COMPLP        ; Compare entire key
  564.     OR    A        ; Clr for equal avoids unecessary equal swaps
  565.  
  566. CMPRTN:    POP    HL        ;
  567.     POP    DE        ;
  568.     RET            ;
  569.  
  570. ;..............................................................................
  571.  
  572. ; Exchange the entries at (HL) and (DE). [ Used by SORT above]
  573. ;
  574. SWAP:    PUSH    DE        ;
  575.     PUSH    HL        ;
  576.  
  577.     LD    B,(IX+ENTLEN)    ; Get entry size
  578. SWAPLP:    LD    A,(DE)        ; Get a corresponding byte from each
  579.     LD    C,(HL)        ;
  580.     EX    DE,HL        ; Exchange the pointers
  581.     LD    (DE),A        ; And re-store the pair of bytes
  582.     LD    (HL),C        ;
  583.     INC    HL        ;
  584.     INC    DE        ;
  585.     DJNZ    SWAPLP        ; Loop; (note- another ex DE,HL not needed)
  586.  
  587.     POP    HL        ;
  588.     POP    DE        ;
  589.     RET            ;
  590.