home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / z3util / for-nxt3.lbr / FOR11.ZZ0 / FOR11.Z80
Encoding:
Text File  |  1993-06-07  |  16.1 KB  |  737 lines

  1. ; FOR.Z80
  2. ;
  3. ; Takes a list of (ambiguous) file specifications as parameters and stores
  4. ; them in a file (FORFILES.SYS), optionally expanding the ambiguous names.
  5. ; Explicit directory specifications are retained in front of the names.
  6. ; The output file FORFILES.SYS is set to System status.  This is an ordinary
  7. ; text file, with one filename (or other list element) on each line.
  8. ;
  9. ; Alternatively, arbitrary strings, all named directories, an ascending
  10. ; sequence of integers, or all current shell variable names may be written
  11. ; to the file.
  12. ;
  13. ; Syntax:
  14. ;
  15. ;    FOR <[du:|dir:]fn.ft> [<[du:|dir:]fn.ft>] [/X]
  16. ;
  17. ;    where the 'X' option indicates that all ambiguous filenames are to be
  18. ;        expanded.  If an ambiguous filename is prefaced with a DU: or DIR:
  19. ;        specification, its expansions will all also contain the directory
  20. ;        specification.
  21. ;
  22. ; -or-
  23. ;
  24. ;    FOR 'one string' "another string" \a third string\ /S
  25. ;
  26. ;    where the 'S' option is REQUIRED to indicate that the list elements
  27. ;        are delimited strings.  Any non-blank character except the virgule
  28. ;        (/) and comma may be used as a delimiter.
  29. ;
  30. ; -or-
  31. ;
  32. ;    FOR /o
  33. ;
  34. ;    where 'o' can be:
  35. ;        D  --  list all named directories
  36. ;        Rn --  list all integers up to that contained in register 'n',
  37. ;           one per line.  The list is zero-based
  38. ;        Nn --  list all integers up to 'n', one per line (zero-based).
  39. ;        V  --  list all currently defined shell variable names.
  40. ;
  41. ;    If the 'Nn' or 'Rn' forms are used and a 1-based list is needed,
  42. ;    the first element can be removed with 'NEXT' and not used.  Any
  43. ;    parameters preceding one of these option specifications will be
  44. ;    ignored.
  45. ;
  46. ; In all circumstances, only one option is appropriate.  As presently written,
  47. ; program control is transferred directly based upon the option, rather than
  48. ; using an array of option flags.
  49. ;
  50. ; Delimiters BETWEEN list elements (whether filenames or strings) may be
  51. ; either spaces or commas.
  52. ;
  53. ;
  54. ; Author: Dreas Nielsen
  55. ; History --
  56. ;    Date        Version        Comments
  57. ;    ----        -------        --------
  58. ;    7/15/86        0.1        First code
  59. ;    1/10/87        0.2        Fixed ambiguous filenames
  60. ;    1/11/87        1.0        First complete version
  61. ;    2/19/89        1.1        Added shell variable name expansion.
  62. ;
  63. ;
  64. ;================[  Equates and External Routines  ]================
  65. ;
  66. VERS    EQU    11
  67. ;
  68. FALSE    EQU    0
  69. TRUE    EQU    NOT FALSE
  70. ;
  71. DEBUG    EQU    FALSE
  72. ;
  73. CR    EQU    0DH
  74. LF    EQU    0AH
  75. BELL    EQU    7
  76. SPACE    EQU    20H
  77. CTRLZ    EQU    1AH
  78. EOF    EQU    1AH
  79. BDOS    EQU    5
  80. INFERR    EQU    1    ;error code for "can't open input file"
  81. OFERR    EQU    2    ;error code for "can't open output file"
  82. RDERR    EQU    3    ;error code for "can't read input file"
  83. WRTERR    EQU    4    ;error code for "can't write output file"
  84. CLZERR    EQU    5    ;error code for "can't close output file"
  85. PARMFL    EQU    '/'
  86. XPARM    EQU    'X'
  87. LINLEN    EQU    300    ;max # of chars in output line
  88. CMDLIN    EQU    080H
  89. SYSFCB    EQU    05CH
  90. BUFSIZ    EQU    8    ;8 128-byte sectors (1k) for I/O buffers
  91. FCBLEN    EQU    36
  92. BSZOFF    EQU    0    ;offset of buffer size indicator from I/O ctl block
  93. BADOFF    EQU    6    ;offset of buffer addr indic. from I/O ctl block start
  94. FCBOFF    EQU    8    ;offset of fcb from I/O ctl block start
  95. ;
  96.     EXT    Z3INIT,QPRINT,SKSP,PRINT,PUTUD,GETUD,LOGUD,DIRF,MFN2
  97.     EXT    CODEND,PUTER2,FXO$OPEN,FX$PUT,FXO$CLOSE
  98.     EXT    ZPRSFN,DIRQ,MFN2,FILLB
  99.     EXT    DNSCAN,FNAME,GETNDR,GETREG,EVAL10,MHLFDC
  100.     EXT    VARLOAD,Z3VARS
  101. ;
  102. ;================[  Beginning of Program  ]================
  103. ;
  104.     DB    'Z3ENV'
  105.     DB    1
  106. Z3ENV:    DW    00
  107.     DB    VERS
  108. ;
  109. START:    LD    HL,(Z3ENV)
  110.     CALL    Z3INIT
  111. ;
  112. ; Reset error flag
  113.     XOR    A
  114.     CALL    PUTER2
  115. ;
  116. ; Save stack and set a new one
  117.     LD    (SAVESP),SP
  118.     LD    HL,STK
  119.     LD    SP,HL
  120. ;
  121. ; Print signon message
  122.     CALL    QPRINT
  123.     DB    'FOR  v. ',[VERS / 10] + '0','.',[VERS MOD 10] + '0',CR,LF,0
  124. ;
  125. ; Save currently logged DU
  126.     CALL    PUTUD
  127. ;
  128. ; Check for no parameters (help)
  129.     LD    A,(SYSFCB+1)
  130.     CP    ' '
  131.     JP    Z,HELP
  132. ;
  133. ; Store null at end of cmdline
  134.     LD    HL,CMDLIN
  135.     LD    A,(HL)
  136.     INC    A
  137.     LD    E,A
  138.     XOR    A
  139.     LD    D,A
  140.     ADD    HL,DE
  141.     LD    (HL),A
  142. ;
  143. ; Allocate space for file list and move command line
  144.     CALL    CODEND
  145.     LD    (PARAMS),HL
  146.     LD    DE,CMDLIN+1
  147. MOVCL:    LD    A,(DE)
  148.     LD    (HL),A
  149.     INC    HL
  150.     INC    DE
  151.     OR    A
  152.     JR    NZ,MOVCL
  153. ;
  154. ; Allocate space for DIR: specification, if needed.
  155.     LD    (DIRNAM),HL
  156.     LD    DE,24
  157.     ADD    HL,DE
  158. ;
  159. ; Allocate filename buffer used with DIRF
  160.     LD    (FNBUF),HL
  161.     LD    DE,13
  162.     ADD    HL,DE
  163. ; Allocate buffer for packed name string
  164.     LD    (NMDEST),HL
  165.     LD    DE,LINLEN
  166.     ADD    HL,DE
  167. ;
  168. ; Allocate output buffer and initialize it
  169.     LD    (OUTPLOC),HL
  170.     CALL    FBINIT        ;allocate I/O ctl buffer for output
  171.     LD    (FREE),HL
  172.     LD    HL,(OUTPLOC)
  173.     LD    DE,OFNAM
  174.     CALL    INITNAM
  175. ;
  176. ; Examine command line for option specification.  If no options are specified,
  177. ; the list is presumed to be of filenames which are not to be expanded or
  178. ; undelimited strings (without embedded spaces or commas).  This routine finds
  179. ; the LAST parameter flag on the line, as there may be some embedded in
  180. ; delimited strings.
  181. GETOPT:
  182.     LD    HL,00        ;zero out parameter address
  183.     LD    (PFADR),HL
  184.     LD    HL,(PARAMS)
  185. GETO2:    LD    A,(HL)
  186.     INC    HL
  187.     OR    A        ;end of list?
  188.     JR    Z,GETO3
  189.     CP    PARMFL
  190.     JR    NZ,GETO2
  191.     LD    (PFADR),HL
  192.     JR    GETO2
  193. ;
  194. GETO3:    LD    HL,(PFADR)
  195.     LD    A,H
  196.     OR    L        ;if this is null...
  197.     JR    Z,RAWFILES    ;...no parameter flag was found
  198. ;
  199. ; Examine char after '/' and proceed accordingly
  200.     CALL    SKSP
  201.     LD    A,(HL)
  202.     CP    'X'
  203.     JR    Z,AMBFILS    ;ambiguous filenames
  204.     CP    'S'
  205.     JP    Z,STRINGS    ;delimited strings
  206.     CP    'D'
  207.     JP    Z,DIRNAMES    ;directory names
  208.     CP    'R'
  209.     JP    Z,REGS        ;register value
  210.     CP    'N'
  211.     JP    Z,NUM        ;integer value
  212.     CP    'V'
  213.     JP    Z,VARS        ; shell variable names
  214.     JP    HELP        ;because it is an unrecognized option
  215. ;
  216. ; Parameter list is unambigous filenames or undelimited strings.
  217. RAWFILES:
  218.     CALL    OPENOUT
  219.     LD    HL,(PARAMS)
  220. RAW1:    LD    A,(HL)        ;skip to first non-delimiter
  221.     INC    HL
  222.     CALL    LISTDEL
  223.     JR    Z,RAW1
  224.     OR    A
  225.     JR    Z,RAW6
  226.     DEC    HL        ;point back 1 to fetch 1st char again
  227. ;
  228. RAW2:    LD    DE,(NMDEST)    ;transfer token
  229. RAW3:    LD    A,(HL)
  230.     INC    HL
  231.     OR    A        ;end of list?
  232.     JR    Z,RAW4
  233.     CALL    LISTDEL        ;space or comma?
  234.     JR    Z,RAW4
  235.     LD    (DE),A
  236.     INC    DE
  237.     JR    RAW3        ;get next char of current token
  238. ;
  239. RAW4:                ;write current token and look for next
  240.     CALL    WRTTOK
  241.     JR    NZ,RAW2        ;next token found -- get and write it
  242. ;
  243. RAW6:                ;end of list found
  244.     CALL    CLOSOUT
  245.     JP    DONE
  246. ;
  247. ;----------------
  248. ; Parameter list is a list of ambiguous filenames.
  249. AMBFILS:
  250.     CALL    OPENOUT
  251.     LD    HL,(PARAMS)    ;save prefix (DU: or DIR:) if it exists
  252. AMB0:    LD    A,(HL)        ;skip to first non-delimiter
  253.     INC    HL
  254.     CALL    LISTDEL        ;is (A) a list delimiter?
  255.     JR    Z,AMB0        ;if so, get next character
  256.     OR    A
  257.     JP    Z,AMB3        ;if end of list, quit
  258.     DEC    HL        ;point back 1 to 1st char of token
  259.     PUSH    HL        ;save starting point
  260.     CALL    NXTDLM        ;see if next delimiter is a colon
  261.     POP    HL        ;get starting addr. back
  262.     LD    DE,(DIRNAM)    ;destination buffer; HL points to source
  263.     CP    ':'
  264.     JR    NZ,NOMOV
  265. ;                ;move DU:/DIR: spec into buffer
  266. MOVDU:    LD    A,(HL)
  267.     LD    (DE),A
  268.     INC    HL
  269.     INC    DE
  270.     CP    ':'
  271.     JR    NZ,MOVDU
  272. ;
  273. NOMOV:    XOR    A        ;null-terminate DU:/DIR: spec buffer
  274.     LD    (DE),A
  275. ;
  276. ; Parse the filename pointed to by HL into FCB format
  277.     PUSH    HL        ;save ptr to filename
  278.     LD    HL,(DIRNAM)
  279.     LD    A,(HL)
  280.     OR    A
  281.     JR    Z,P2        ;don't scan if no DU/DIR
  282.     XOR    A        ;DU before DIR
  283.     CALL    DNSCAN
  284.     JR    Z,P2        ;if invalid, stay here
  285.     CALL    LOGUD
  286. P2:    POP    HL        ;get filename
  287.     LD    DE,SYSFCB
  288.     CALL    FNAME        ;parse filename into FCB
  289.     JR    Z,AMB2
  290.     LD    (CLPTR),HL    ;save pointer to tokens
  291.     LD    HL,(FREE)    ;buffer area for directory load
  292.     LD    A,10100000B    ;non-system files sorted by name
  293.     CALL    DIRQ        ;load directory
  294.     CALL    GETUD        ;return home to write file
  295. ;
  296.     INC    HL        ;point to first name
  297.     EX    DE,HL        ;...with DE
  298. WRNAMS:    LD    A,B        ;for all filenames in buffer...
  299.     OR    C
  300.     JR    Z,WRNAM3
  301.     PUSH    DE        ;(save ptr to name)
  302.     LD    DE,(DIRNAM)    ;...move directory name to write buffer
  303.     LD    HL,(NMDEST)
  304. WRNAM1:    LD    A,(DE)
  305.     INC    DE
  306.     OR    A
  307.     JR    Z,WRNAM2
  308.     LD    (HL),A
  309.     INC    HL
  310.     JR    WRNAM1
  311. WRNAM2:    POP    DE        ;HL = mem buffer, DE = name
  312. ;
  313.     PUSH    BC        ;write 13 nulls, so name will be null-term.
  314.     LD    B,13
  315.     XOR    A
  316.     CALL    FILLB
  317.     POP    BC
  318. ;
  319.     CALL    MFN2        ;convert fname to packed string in wrt buffer
  320.     PUSH    DE
  321. ;
  322.     CALL    WRTSTR        ;write name to file
  323.     POP    DE
  324.     LD    HL,16        ;set DE to point to next name
  325.     ADD    HL,DE
  326.     EX    DE,HL
  327.     DEC    BC        ;count down number of names written
  328.     JR    WRNAMS
  329. ;
  330. WRNAM3:                ;done with this token, look for next
  331.     LD    HL,(CLPTR)
  332. AMB2:    LD    A,(HL)
  333.     INC    HL
  334.     OR    A
  335.     JR    Z,AMB3
  336.     CP    PARMFL
  337.     JR    Z,AMB3
  338.     CALL    LISTDEL
  339.     JR    Z,AMB2
  340.     DEC    HL        ;if another token found, point to 1st char
  341.     JP    AMB0        ;go back and process it
  342. ;
  343. AMB3:    CALL    CLOSOUT
  344.     JP    DONE
  345. ;
  346. ;
  347. ;----------------
  348. ; Chop parameter list into delimited strings.
  349. ;
  350. STRINGS:
  351.     CALL    OPENOUT
  352.     LD    HL,(PARAMS)
  353. STR1:    LD    A,(HL)        ;skip to first non-comma, non-space
  354.     INC    HL
  355.     CALL    LISTDEL
  356.     JR    Z,STR1
  357.     OR    A
  358.     JR    Z,STR5
  359.     DEC    HL
  360. ;
  361. STR2:    LD    A,(HL)
  362.     LD    (DELIM),A    ;save delimiter for comparison
  363.     INC    HL
  364.     LD    DE,(NMDEST)
  365. STR3:    LD    A,(HL)
  366.     INC    HL
  367.     OR    A
  368.     JR    Z,STR4
  369. DELIM    EQU    $+1
  370.     CP    00        ;the current string delimiter is used here
  371.     JR    Z,STR4
  372.     LD    (DE),A
  373.     INC    DE
  374.     JR    STR3
  375. ;
  376. STR4:
  377.     OR    A        ;if not null, bump HL by 1 more to account...
  378.     JR    Z,STR5        ;...for DEC HL in WRTTOK
  379.     INC    HL
  380. STR5:    CALL    WRTTOK
  381.     JR    NZ,STR2
  382. ;
  383. STR6:
  384.     CALL    CLOSOUT
  385.     JP    DONE
  386. ;
  387. ;
  388. ;  List all directory names.
  389. ;
  390. DIRNAMES:
  391.     CALL    GETNDR
  392.     JP    Z,DONE
  393.     LD    A,(HL)
  394.     JP    Z,DONE
  395. ; There is a buffer and there is at least one entry in it
  396.     CALL    OPENOUT
  397. DIRN1:    LD    A,(HL)
  398.     OR    A
  399.     JR    Z,DIRNZ        ; end of list reached
  400.     INC    HL
  401.     INC    HL        ; now pointing to name
  402.     PUSH    HL        ; save this pointer
  403.     LD    DE,(NMDEST)    ; transfer name to output buffer
  404.     LD    B,8
  405. DIRN2:    LD    A,(HL)
  406.     CP    ' '
  407.     JR    Z,DIRN3
  408.     LD    (DE),A
  409.     INC    HL
  410.     INC    DE
  411.     DJNZ    DIRN2
  412. ;
  413. DIRN3:    LD    A,':'
  414.     LD    (DE),A
  415.     INC    DE
  416.     XOR    A
  417.     LD    (DE),A
  418.     CALL    WRTSTR
  419. ;
  420.     POP    HL        ; advance to next directory name
  421.     LD    DE,16
  422.     ADD    HL,DE
  423.     JR    DIRN1
  424. ;
  425. DIRNZ:    CALL    CLOSOUT        ; all done with directory names
  426.     JP    DONE
  427. ;
  428. ;
  429. ; Write all numbers up to the value contained in the register specified by
  430. ; the character at (HL+1).  The list will be zero-based and will run up to
  431. ; the register value - 1.
  432. ;
  433. REGS:
  434.     INC    HL
  435.     LD    A,(HL)
  436.     OR    A
  437.     JR    Z,REGERR    ; premature eol
  438.     SUB    '0'
  439.     CP    0
  440.     JR    C,REGERR    ; illegal value
  441.     CP    10
  442.     JR    NC,REGERR
  443. ; A register value is specified and it is legal
  444.     LD    B,A
  445.     CALL    GETREG
  446.     LD    E,A
  447.     LD    D,0
  448.     JR    WRTNUMS
  449. ;
  450. REGERR:
  451.     CALL    PRINT
  452.     DB    'Improper register value.',CR,LF,0
  453.     XOR    A
  454.     DEC    A
  455.     CALL    PUTER2
  456.     JP    DONE
  457. ;
  458. ;
  459. ; Write a zero-based list of numbers, up to (but not including) the value
  460. ; indicated by the string at (HL+1).
  461. ;
  462. NUM:
  463.     INC    HL
  464.     LD    A,(HL)
  465.     OR    A
  466.     JR    Z,NUMERR
  467.     CALL    EVAL10
  468.     JR    WRTNUMS
  469. ;
  470. NUMERR:    CALL    PRINT
  471.     DB    'Unspecified numeric argument.',CR,LF,0
  472.     XOR    A
  473.     DEC    A
  474.     CALL    PUTER2
  475.     JP    DONE
  476. ;
  477. ;  Write out numbers up to the value in DE if DE > 0
  478. WRTNUMS:
  479.     LD    A,E
  480.     OR    D
  481.     JP    Z,DONE        ; don't write anything if arg is 0
  482.     PUSH    DE
  483.     CALL    OPENOUT
  484.     POP    DE
  485.     LD    HL,00        ; HL counts up to limit in DE
  486. WRTNUM1:
  487.     PUSH    DE        ; save limit
  488.     LD    DE,(NMDEST)    ; format & write number
  489.     CALL    MHLFDC
  490.     XOR    A
  491.     LD    (DE),A
  492.     PUSH    HL
  493.     CALL    WRTSTR
  494.     POP    HL
  495.     POP    DE        ; get limit back
  496.     INC    HL        ; compute next number to write
  497.     PUSH    HL        ; save it while comparing to limit
  498.     OR    A        ; clear carry flag
  499.     SBC    HL,DE        ; at limit yet?
  500.     LD    A,H
  501.     OR    L
  502.     POP    HL        ; get current value back
  503.     JR    Z,WRTNUMZ    ; if at limit, go quit
  504.     JR    WRTNUM1        ; else go back and write the next number
  505. ;
  506. WRTNUMZ:
  507.     CALL    CLOSOUT
  508.     JP    DONE
  509. ;
  510. ;
  511. ; Write a list of all currently defined shell variable names.
  512. VARS:
  513.     LD    HL,(FREE)
  514.     CALL    VARLOAD
  515.     JP    NZ,DONE
  516.     LD    (FREE),HL
  517.     LD    HL,(Z3VARS)    ; origin of list--same as (FREE) passed.
  518.     LD    A,(HL)
  519.     CP    1AH        ; eof?
  520.     JP    Z,DONE
  521.     CALL    OPENOUT
  522. ;
  523. ; Transfer each variable name to the name buffer, null terminate, and
  524. ; write out.
  525.     LD    HL,(Z3VARS)
  526. ;
  527. ; While not eof (^Z at HL)
  528. VARS1:    LD    A,(HL)
  529.     CP    1AH
  530.     JP    Z,VARS5
  531. ; Transfer up to 8 characters to destination buffer.
  532.     LD    DE,(NMDEST)
  533.     LD    B,8
  534. VARS2:    LD    A,(HL)
  535.     CP    ' '
  536.     JR    Z,VARS3        ; Exit loop if end of name found
  537.     LD    (DE),A
  538.     INC    HL
  539.     INC    DE
  540.     JR    NZ,VARS2
  541. VARS3:                ; Terminate name
  542.     XOR    A
  543.     LD    (DE),A
  544. ; Write out name.
  545.     PUSH    HL
  546.     CALL    WRTSTR
  547.     POP    HL
  548. ; Scan to end of this definition, skip to next name.
  549.     XOR    A
  550.     LD    BC,0FFFFH
  551.     CPIR
  552. ; End while
  553.     JR    VARS1
  554. ;
  555. VARS5:
  556.     CALL    CLOSOUT
  557.     JP    DONE
  558. ;
  559. ;
  560. ;
  561. ; Print help message and fall through to exit.
  562. HELP:
  563.     CALL    PRINT
  564.     DB    'Syntax is:',CR,LF
  565.     DB    '   FOR <[du:|dir:]fn.ft> [<[du:|dir:]fn.ft>] [/x]',CR,LF
  566.     DB    'or',CR,LF
  567.     DB    '   FOR ''one string'' "another string" \a third string\ /s',CR,LF
  568.     DB    'or',CR,LF
  569.     DB    '   FOR /o',CR,LF
  570.     DB    'Options:'CR,LF
  571.     DB    '   x -- Expand ambiguous filenames',CR,LF
  572.     DB    '   s -- List elements are delimited strings',CR,LF
  573.     DB    '   o -- May be:',CR,LF
  574.     DB    '            D  --  list all named directories',CR,LF
  575.     DB    '            Rn --  list all integers up to that contained in register ''n'',',CR,LF
  576.     DB    '                   one per line.  The list is zero-based.',CR,LF
  577.     DB    '            Nn --  list all integers up to ''n'', one per line (zero-based).',CR,LF
  578.     DB    '            V  --  list all current shell variable names.',CR,LF
  579.     DB    0
  580. ;
  581. ;
  582. ; Clean up and exit program.
  583. DONE:
  584.     CALL    GETUD
  585.     LD    SP,(SAVESP)
  586.     RET
  587. ;
  588. ;
  589. ;================[  Subroutines  ]================
  590. ;
  591. ; Initialize file I/O control buffers.
  592. ; Enter with  HL = first free address in memory
  593. ;             B  = number of 128-byte sectors for the file buffer
  594. ; Return:     HL = first free address after buffer
  595. ;
  596. FBINIT:
  597.     PUSH    DE
  598.     PUSH    BC
  599.     LD    (HL),B
  600.     LD    DE,BADOFF    ;loc of buf addr in I/O ctl block
  601.     ADD    HL,DE
  602.     PUSH    HL
  603.     LD    DE,[FCBLEN + FCBOFF - BADOFF]
  604.     ADD    HL,DE
  605.     EX    DE,HL
  606.     POP    HL
  607.     LD    (HL),E
  608.     INC    HL
  609.     LD    (HL),D
  610.     EX    DE,HL        ;get buf start addr in HL
  611.     LD    DE,128        ;incr HL by buf len in bytes
  612. FBINI1:    ADD    HL,DE
  613.     DJNZ    FBINI1
  614.     POP    BC
  615.     POP    DE
  616.     RET
  617. ;
  618. ;----------------
  619. ; Move filename into fcb of I/O ctl block.  Enter with HL = I/O ctl blk addr,
  620. ; DE = addr of string to move.  Drive is set to current.
  621. INITNAM:
  622.     PUSH    BC
  623.     PUSH    DE        ;save while adding fcb offset
  624.     LD    DE,FCBOFF
  625.     ADD    HL,DE        ;point to input fcb
  626.     XOR    A        ;set current drive
  627.     LD    (HL),A
  628.     INC    HL        ;point to name field of fcb
  629.     POP    DE        ;get source addr
  630.     EX    DE,HL        ;put dest addr in DE, source in HL
  631.     LD    BC,11
  632.     LDIR
  633.     POP    BC        ;restore original contents
  634.     RET
  635. ;
  636. ;----------------
  637. ; Open output file
  638. OPENOUT:
  639.     LD    DE,(OUTPLOC)
  640.     CALL    FXO$OPEN
  641.     RET
  642. ;
  643. ;----------------
  644. ; Close output file
  645. CLOSOUT:
  646.     LD    DE,(OUTPLOC)
  647.     CALL    FXO$CLOSE
  648.     RET
  649. ;
  650. ;----------------
  651. ; Find next delimiter in string pointed to by HL.  Return with delim. in A,
  652. ; HL pointing past char.  Delimiters are:
  653. ;    <NULL>  <SPACE>  /  ,  :
  654. NXTDLM:    LD    A,(HL)
  655.     INC    HL
  656.     CP    ':'
  657.     RET    Z
  658.     CP    ','
  659.     RET    Z
  660.     CP    ' '
  661.     RET    Z
  662.     OR    A
  663.     RET    Z
  664.     CP    '/'
  665.     RET    Z
  666.     JR    NXTDLM
  667. ;
  668. ;----------------
  669. ; Is (A) a list-element delimiter (a comma or space?).   Return Z if true.
  670. LISTDEL:
  671.     CP    SPACE
  672.     RET    Z
  673.     CP    ','
  674.     RET
  675. ;
  676. ;----------------
  677. ; Write the string pointed to by NMDEST to the output file.  String will be
  678. ; terminated with a CR/LF.
  679. WRTSTR:
  680.     LD    DE,(OUTPLOC)
  681.     LD    HL,(NMDEST)
  682. WRT2:    LD    A,(HL)
  683.     INC    HL
  684.     OR    A
  685.     JR    Z,WRT3
  686.     CALL    FX$PUT
  687.     JR    WRT2
  688. WRT3:    LD    A,CR
  689.     CALL    FX$PUT
  690.     LD    A,LF
  691.     CALL    FX$PUT
  692.     RET
  693. ;
  694. ;----------------
  695. ; Null-terminate the current token and write it out, then search for the next.
  696. ; Return Z if the end of the input has been reached, NZ otherwise.  On return,
  697. ; HL points to the next non-blank, non-comma character.
  698. WRTTOK:
  699.     XOR    A        ;store null at end of token
  700.     LD    (DE),A
  701.     PUSH    HL
  702.     CALL    WRTSTR
  703.     POP    HL
  704.     DEC    HL        ;point to delim again in case it's a null
  705. WRTT:    LD    A,(HL)        ;skip over multiple delimiters
  706.     INC    HL
  707.     OR    A        ;No blank lines can be generated by multiple
  708.     RET    Z        ;delimiters.
  709.     CP    PARMFL
  710.     RET    Z
  711.     CALL    LISTDEL
  712.     JR    Z,WRTT
  713.     DEC    HL        ;we'll fetch the non-delimiter again
  714.     RET
  715. ;
  716. ;
  717. ;================[  Storage  ]================
  718. ;
  719. SAVESP:    DS    2
  720. PARAMS:            ;addr of list of files (command line)
  721.     DS    2
  722. FREE:    DS    2    ;addr of beginning of free memory
  723. XPAND:    DB    0    ;flag: NZ=expand ambiguous names, 0=don't.
  724. DIRNAM:    DS    2    ;addr of buffer for directory name
  725. FNBUF:    DS    2    ;addr of buffer for file name
  726. NMDEST:    DS    2    ;address of destn for packed name string
  727. PFADR:    DS    2    ;address following last parameter flag in command line
  728. CLPTR:    DS    2    ;temp. storage for pointer to cmd line
  729. OUTPLOC:
  730.     DS    2    ;addr of output file buffer
  731. OFNAM:    DB    'FORFILESS','Y'+80H,'S'
  732. STKBOT:    DS    48
  733. STK:    DS    2
  734. ;
  735. ;
  736.     END    START
  737.