home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / txtutl / fixtex12.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  22.0 KB  |  1,096 lines

  1. ;
  2. ;             FIXTEX.ASM version 1.2
  3. ;               by Paul L. Kelley
  4. ;                   based on
  5. ;             FILTER.ASM version 1.1
  6. ;                 and
  7. ;             FILTEX.ASM version 1.0
  8. ;            by Keith Petersen, W8SDZ
  9. ;09/10/84 - Fixed bug in FLTESC routine, that failed to reset high bit
  10. ;           if FLTESC option is selected.
  11. ;        Did this by storing byte back to input buffer location
  12. ;            after ANI 7Fh, so that when its recalled from there after
  13. ;            various tests it comes back with bit 7 reset.
  14. ;
  15. ;                        EOS
  16. ;
  17. ;01/14/83 - Did the following:
  18. ;   1. Fixed bug (missing ENDIF) in version 1.0,
  19. ;   2. Rewrote instructions on user-definable options
  20. ;      to avoid some possible confusion.
  21. ;                                            EOS
  22. ;01/03/83 - Did the following:
  23. ;
  24. ;    1. Changed to assemble with DRI's ASM,
  25. ;    2. Changed so that if input file is FILENAME.ABC then output
  26. ;        file is FILENAME.XYZ where the various XYZ's are given
  27. ;        below or, if renaming is chosen, the output file has
  28. ;        the original file name and type and the input file name
  29. ;        has the file type BAK,
  30. ;    3. Modified so that output file can be on different drive
  31. ;        from input,
  32. ;    4. Added routines to output several types of files depending
  33. ;        on assembly time switches, these switches can be set to
  34. ;        do a number of operations (some are mutually exclusive).
  35. ;        All cases pad the last sector with EOFs. The operations
  36. ;        are:
  37. ;      a. leave text unchanged, filetype=PAD
  38. ;      b. delete all control characters except CR, LF and TAB,
  39. ;        filetype=FIX
  40. ;      c. insert LF after each CR if absent, filetype=ALF
  41. ;      d. insert CR before each LF if absent, filetype=ACR
  42. ;      e. delete extraneous LF (those not following CR), filetype=FEL
  43. ;      f. delete LF, filetype=FLF
  44. ;      g. insert one space on each blank line, filetype=ASP
  45. ;      h. delete LF and insert a space on each blank line, filetype=SFL
  46. ;      i. replace TAB with spaces, filetype=FTB
  47. ;      j. delete LF and replace TAB with spaces, filetype=FLT
  48. ;      k. replace TAB with spaces and insert a space on each blank line,
  49. ;        filetype=SRT
  50. ;      l. delete LF and replace TAB with spaces and insert a space
  51. ;        on each blank line,
  52. ;        filetype=FBB (canonical bulletin board file)
  53. ;      m. delete any character following ESC, filetype=FES
  54. ;      n. replace more than one space with TAB where possible,
  55. ;        filetype=RSP
  56. ;      o. replace more than one space with TAB where possible
  57. ;        except in 'qouted' strings,
  58. ;        filetype=FSM (canonical assembly file)
  59. ;      p. insert a tab at start of each line, filetype=ATB
  60. ;      q.  insert an arbitrary number of spaces at start of each line,
  61. ;        filetype=ANS
  62. ;
  63. ;Options f, g, h, i, j, k and l may be useful when sending files to
  64. ;bulletin boards and mainframes. Option m may be useful when capturing
  65. ;text from mainframes which control your terminal in full screen mode.
  66. ;Option o can shorten assembly language files.
  67. ;                        P.L.Kelley
  68. ;
  69. ;From FILTER.ASM Version 1.1 - Revised 01/27/81
  70. ;This program copies any ASCII file and filters out (ignores)
  71. ;all control characters except CR, LF, and TAB.  It also sets
  72. ;the high order bit of all characters to zero so that files
  73. ;created with WordStar or other text processing programs can
  74. ;be read by MBASIC.  The filtered copy of the of the file is
  75. ;created as 'FILTER.FIL' on the default drive.  The source
  76. ;file is left intact.  If the original file's EOF (1AH) is
  77. ;not at the physical end of the last sector, this program
  78. ;will pad the last sector with EOF's.  This is useful for
  79. ;'cleaning up' a file which was originally created by MBASIC
  80. ;or text editors which do not pad the last sector with EOF's.
  81. ;                         Keith Petersen, W8SDZ
  82. ;
  83. ;Command: FILTER [drive:]<filename.filetype> [drive:]
  84. ;
  85. FALSE    equ    0
  86. TRUE    equ    0ffh
  87. ;
  88. ; ********** USER DEFINABLE AREA BEGINS HERE *****************
  89.  
  90. renfil    equ    FALSE    ;if true, output file has name of
  91.             ; input file and input file has file
  92.             ; type BAK.
  93.             ; if false, output file is given
  94.             ; distinctive file type and input file
  95.             ; is not renamed.
  96. ;
  97. fltctl    equ    FALSE     ;filters control chars (exc. CR,LF,TAB)
  98.             ; FLTCTL is independent of other options,
  99.             ; but should probably be set TRUE if
  100.             ; FLTESC (below) is TRUE.
  101. ;
  102.  
  103. ; +++++++  Read the following carefully - easy to go wrong ++++++
  104.  
  105. ;The remaining options fall into two mutually-exlusive groups, i.e.,
  106. ; ALL of the other group's options must be FALSE if any options
  107. ; in a Group a are set TRUE.
  108.  
  109. ;In the case of GROUP ONE, only one of the seven possible
  110. ; options may be true (and all Group Two options must be FALSE).
  111.  
  112. ;In the case of GROUP TWO, one or more of the three options
  113. ; may be TRUE (and all of Group One options must be FALSE)
  114. ;
  115.  
  116. ;+++++ GROUP ONE Options start here - ONLY ONE may be TRUE,
  117. ;                                     AND all GROUP TWO Options
  118. ;                                     must be FALSE if a GROUP ONE
  119. ;                                     Options is TRUE. ++++++++++++++
  120.  
  121. addlf    equ    FALSE    ;add LF after CR if missing
  122. addcr    equ    FALSE    ;add CR before LF if missing
  123. addnsp    equ    FALSE    ;add spaces at the start of each line
  124. fltelf    equ    FALSE    ;filter LF if not after CR
  125. fltesc    equ    FALSE     ;filter character after ESC (you will likely
  126.             ; also want to set ftlctl to TRUE)
  127. spcrpl    equ    FALSE    ;replace spaces with TAB (where possible)
  128. addtab    equ    FALSE    ;add TAB at the start of each line
  129.             ; (see below also)
  130.             ; End GROUP ONE Options
  131. ;
  132.             ; Subordinate GROUP ONE Option:
  133. fltasm    equ    FALSE    ;Do not replace spaces in 'quoted' strings.
  134.             ; This equate may be TRUE only if SPCRPL in
  135.             ; Group 1 (above) is also TRUE.
  136. ;
  137. ; ~~~~~~~~ END GROUP ONE - BEGIN GROUP TWO Options ~~~~~~~~~~~~~~~
  138.  
  139. ; ++++++++++++++++++++++ ANY of ALL Group TWO Options may be TRUE,
  140. ;                        but ONLY is ALL Group ONE Optiond are FALSE
  141. ;                                      ++++++++++++++++++++++++++++
  142.  
  143. filtlf    equ    FALSE    ;filter all LF
  144. addsp    equ    FALSE    ;add one space on each blank line
  145. tabrpl    equ    FALSE    ;replace TAB with spaces
  146.  
  147. ; ~~~~~~~~~~~~~~ End GROUP TWO Options ~~~~~~~~~~~~~~~
  148. ;
  149. numspc    equ    8    ;defines number of spaces to add at
  150.             ; start of line if ADDNSP is TRUE.
  151.             ; May change to suit yourself.
  152. ;
  153. tablen    equ    8    ;defines length of TAB inserted by TABRPL.
  154.             ; May change to suit yourself
  155. ;
  156. ; ******************** END OF USER DEFINABLE AREA ********
  157.  
  158. ; NOTE:  Although you could probably enlarge BSIZE (below) up
  159. ;        to a value of TPA - 2 (in K bytes), it probably wouldn't
  160. ;        improve speed very much.  Unless you know exactly what
  161. ;        you're doing, and why, you're better off leaving the
  162. ;        value for BSIZE as it is.
  163. ;
  164. ;Define write buffer size
  165. BSIZE    EQU    16    ;<--NOW SET FOR 16k
  166. ;
  167.  
  168. ;
  169. ;BDOS equates
  170. ;
  171. WBOOT    EQU    0    ;WARM BOOT ENTRY ADRS
  172. WRCON    EQU    2    ;WRITE CHARACTER TO CONSOLE
  173. BDOS    EQU    5    ;CP/M BDOS ENTRY ADRS
  174. PRINT    EQU    9    ;PRINT STRING (DE) UNTIL '$'
  175. OPEN    EQU    15    ;OPEN DISK FILE
  176. close    equ    16
  177. erase    equ    19
  178. READ    EQU    20    ;READ SEQUENTIAL FILE
  179. write    equ    21
  180. make    equ    22
  181. rename    equ    23
  182. STDMA    EQU    26    ;SET DMA ADDRESS
  183. FCB    EQU    5CH    ;DEFAULT FILE CONTROL BLOCK
  184. ;
  185. cr    equ    13
  186. lf    equ    10
  187. tab    equ    9
  188. eof    equ    1ah
  189. esc    equ    1bh
  190. quote    equ    ''''
  191. cmnt    equ    ';'
  192. del    equ    7fh
  193. mask    equ    7fh
  194. ;
  195. ;Program starts here
  196. ;
  197.     ORG    100H
  198. ;
  199. START:
  200.     LXI    SP,STACK  ;SET STACK POINTER
  201.     CALL    ILPRT    ;PRINT
  202.     DB    CR,LF,'FXTXT version 1.2 - ASCII file utility',CR,LF
  203.     DB        'Resets all high bits',cr,lf,0
  204.     if    fltctl
  205.     call    ilprt
  206.     db    'Deletes all control characters except CR'
  207.     endif    ;fltctl
  208.     if    ((not filtlf) or (not tabrpl)) and fltctl
  209.     db    ', LF and TAB'
  210.     endif    ;((not filtlf) or (not tabrpl)) and fltctl
  211.     if    filtlf and (not tabrpl) and fltctl
  212.     db    ' and TAB'
  213.     endif    ;filtlf and (not tabrpl) and fltctl
  214.     if    fltelf and (not tabrpl) and fltctl
  215.     db    ', TAB and LF following CR'
  216.     endif    ;fltelf and (not tabrpl) and fltctl
  217.     if    tabrpl and (not filtlf) and fltctl
  218.     db    ' and LF'
  219.     endif    ;tabrpl and (not filtlf) and fltctl
  220.     if    fltctl
  221.     db    cr,lf,0
  222.     endif    ;fltctl
  223.     if    (not fltctl) and filtlf
  224.     call    ilprt
  225.     db    'Deletes LF',cr,lf,0
  226.     endif    ;(not fltctl) and filtlf
  227.     if    (not filtlf) and fltelf
  228.     call    ilprt
  229.     db    'Deletes LF not after CR',cr,lf,0
  230.     endif    ;(not filtlf) and fltelf
  231.     if    addlf or addcr or addsp or addtab or fltesc
  232.     call    ilprt
  233.     endif    ;addlf or addcr or addsp or addtab or fltesc
  234.     if    addlf
  235.     db    'Inserts LF after CR if missing'
  236.     endif    ;addlf
  237.     if    addcr
  238.     db    'Inserts CR before LF if missing'
  239.     endif    ;addcr
  240.     if    addsp
  241.     db    'Inserts a space on blank lines'
  242.     endif    ;addsp
  243.     if    fltesc
  244.     db    'Deletes character after ESC'
  245.     endif    ;fltesc
  246.     if    addtab
  247.     db    'Adds a TAB at the start of each line'
  248.     endif    ;addtab
  249.     if    addlf or addcr or addsp or addtab or fltesc
  250.     db    cr,lf,0
  251.     endif    ;addlf or addcr or addsp or addtab or fltesc
  252.     if    spcrpl or tabrpl
  253.     call    ilprt
  254.     endif    ;spcrpl or tabrpl
  255.     if    tabrpl
  256.     db    'Replaces TAB with spaces'
  257.     endif    ;tabrpl
  258.     if    spcrpl
  259.     db    'Replaces spaces with TAB where possible'
  260.     endif    ;spcrpl
  261.     if    fltasm
  262.     db    ' except in ''quoted'' strings'
  263.     endif    ;fltasm
  264.     if    spcrpl or tabrpl
  265.     db    cr,lf,0
  266.     endif    ;spcrpl or tabrpl
  267.     if    addnsp
  268.     call    ilprt
  269.     db    'Adds ',0
  270.     lxi    h,numspc
  271.     call    decout
  272.     call    ilprt
  273.     db    ' spaces at the start of each line',cr,lf,0
  274.     endif    ;addnsp
  275.     lda    ftype
  276.     cpi    0
  277.     jnz    nofix
  278.     if    not fltctl
  279.     call    ilprt
  280.     db    'Text unchanged',cr,lf,0
  281.     lxi    h,padftp
  282.     endif    ;not fltctl
  283.     if    fltctl
  284.     lxi    h,fixftp
  285.     endif    ;filctl
  286.     lxi    d,ftype
  287.     mvi    b,3
  288.     call    move
  289. nofix:
  290.     if    not renfil
  291.     lxi    d,outftp
  292.     lxi    h,ftype
  293.     mvi    b,3
  294.     call    move
  295.     call    ilprt
  296.     db    'Output file type is '
  297. outftp:    db    '   ',cr,lf,0
  298.     endif    ;not renfil
  299.     if    renfil
  300.     call    ilprt
  301.     db    'Input file type will be changed to BAK',cr,lf,0
  302.     endif    ;renfil
  303.     LDA    FCB+1
  304.     CPI    ' '    ;FILENAME THERE?
  305.     JNZ    OPENIT    ;YES, GO OPEN IT
  306.     CALL    EXIT    ;PRINT MSG THEN EXIT
  307.     DB    'Usage: FIXTEX [drive:]<filename.filetype> [drive:]',CR,LF
  308.     DB    '       [ ] = optional, < > = required$'
  309. ;
  310. ;Open source file
  311. ;
  312. OPENIT:    LXI    D,FCB
  313.     MVI    C,OPEN
  314.     CALL    BDOS
  315.     INR    A    ;CHECK FOR NO OPEN
  316.     JNZ    DECFIL    ;NO ERROR, CONTINUE
  317.     CALL    EXIT
  318.     DB    '++ SOURCE FILE NOT FOUND ++$'
  319. ;
  320. ;Check for destination drive and erase then open output file
  321. ;
  322. decfil:    lxi    h,80h
  323.     mvi    d,0
  324.     mov    e,m
  325.     dad    d
  326.     mov    a,m
  327.     cpi    ':'
  328.     mvi    a,0
  329.     jnz    nodest
  330.     dcx    h
  331.     mov    a,m
  332.     sbi    'A'
  333.     cpi    16
  334.     jnc    wrgdest
  335.     inr    a
  336. nodest:    sta    fcb2
  337.     lxi    h,fcb+1
  338.     lxi    d,fcb2+1
  339.     mvi    b,8
  340.     call    move
  341.     lxi    d,fcb2
  342.     mvi    c,erase
  343.     call    bdos
  344.     lxi    d,fcb2
  345.     mvi    c,make
  346.     call    bdos
  347.     CALL    ILPRT    ;PRINT:
  348.     DB    'Input and output files open',CR,LF,CR,LF,0
  349. ;
  350. ;Read sector from source file
  351. ;
  352. READLP:    LXI    D,80H
  353.     MVI    C,STDMA
  354.     CALL    BDOS
  355.     LXI    D,FCB
  356.     MVI    C,READ
  357.     CALL    BDOS
  358.     ORA    A    ;READ OK
  359.     JZ    WRDISK    ;YES, SEND IT TO OUTPUT
  360.     CPI    1    ;END-OF-FILE?
  361.     JZ    padeof    ;TRANSFER DONE, CLOSE, EXIT
  362.     CALL    ERXIT
  363.     DB    '++ SOURCE FILE READ ERROR ++$'
  364. ;
  365. ;Write sector to output file (with buffering)
  366. ;
  367. WRDISK:    LXI    H,80H    ;READ BUFFER ADRS
  368. ;
  369. WRDLOP:
  370. ;
  371.     if    addlf
  372.     lda    crflg
  373.     ora    a
  374.     mov    a,m
  375.     jz    skip2
  376.     cpi    lf
  377.     jz    putchr
  378.     call    more
  379.     dcr    l
  380.     mvi    a,lf
  381.     jmp    putchr
  382.     endif    ;addlf
  383. ;
  384.     if    tabrpl
  385.     lda    tabflg
  386.     ora    a
  387.     jz    skip
  388.     lda    tabcnt
  389.     dcr    a
  390.     sta    tabcnt
  391.     jz    endtab
  392.     dcr    l
  393.     call    more
  394.     mvi    a,' '
  395.     jmp    putchr
  396. endtab:    xra    a
  397.     sta    tabflg
  398.     endif    ;tabrpl
  399. ;
  400.     if    fltasm
  401.     mov    a,m
  402.     cpi    cmnt
  403.     jnz    nocmnt
  404.     lda    quoflg
  405.     ora    a
  406.     jnz    nocmnt
  407.     mvi    a,true
  408.     sta    cmtflg
  409.     jmp    spctst
  410. nocmnt:    lda    cmtflg
  411.     ora    a
  412.     jnz    spctst
  413.     mov    a,m
  414.     cpi    quote
  415.     jnz    noflip
  416.     lda    quoflg
  417.     cma
  418.     sta    quoflg
  419. noflip:    lda    quoflg
  420.     ora    a
  421.     jnz    skip
  422.     endif    ;fltasm
  423. ;    
  424.     if    spcrpl
  425. spctst:    lda    spcflg
  426.     ora    a
  427.     jnz    spcst2
  428.     mov    a,m
  429.     cpi    ' '
  430.     jz    spcset
  431.     endif    ;spcrpl    
  432. ;
  433. skip:    MOV    A,M    ;GET BYTE FROM READ BUFFER
  434. skip2:    CPI    eof    ;END OF FILE MARKER ?
  435.     JZ    padeof    ;TRANSFER DONE, CLOSE, EXIT
  436. ;
  437.     if    addtab
  438.     lda    crflg
  439.     ora    a
  440.     mov    a,m
  441.     jz    skip3
  442.     cpi    lf
  443.     jz    putcrlf
  444.     call    more
  445.     dcr    l
  446.     mvi    a,tab
  447.     jmp    putchr
  448.     endif    ;addtab
  449. ;
  450.     if    addnsp
  451.     lda    crflg
  452.     ora    a
  453.     mov    a,m
  454.     jz    skip3
  455.     cpi    lf
  456.     jz    putcrlf
  457.     call    more
  458.     dcr    l
  459.     lda    spccnt
  460.     dcr    a
  461.     sta    spccnt
  462.     mvi    a,' '
  463.     jz    putchr
  464.     jmp    putcrlf
  465.     endif    ;addnsp
  466. ;
  467. skip3:    ANI    mask    ;STRIP PARITY BIT
  468.     mov    m,a    ;put into memory with high bit set, in case
  469.             ; we need it later (change for bugfix in 1.2)
  470.  
  471.     CPI    del    ;DEL (RUBOUT) ?
  472.     JZ    nIGNOR    ;YES, IGNORE IT
  473.     CPI    ' '    ;SPACE OR ABOVE?
  474.     JNC    PUTCHR    ;YES GO WRITE IT
  475. ;
  476.     if    addcr
  477.     lda    crflg
  478.     ora    a
  479.     mov    a,m
  480.     jnz    lftest
  481.     cpi    lf
  482.     jnz    crtest
  483.     mvi    a,true
  484.     sta    crflg
  485.     call    more
  486.     dcr    l
  487.     mvi    a,cr
  488.     jmp    putcrlf
  489. lftest:    cpi    lf
  490.     jmp    putchr
  491.     endif    ;addcr
  492. ;
  493.     if    fltelf
  494.     lda    crflg
  495.     ora    a
  496.     mov    a,m
  497.     jnz    lftest
  498.     cpi    lf
  499.     jz    ignore
  500. lftest:    cpi    lf
  501.     jz    putchr
  502.     endif    ;fltelf
  503. ;
  504.     if    not (filtlf or fltelf or addcr or addtab or addnsp)
  505. lftest:    CPI    LF    ;LINE FEED ?
  506.     JZ    PUTcrlf    ;YES GO WRITE IT
  507.     endif    ;not (filtlf or fltelf or addcr or addtab or addnsp)
  508. ;
  509.     if    filtlf
  510.     cpi    lf
  511.     jz    ignore
  512.     endif    ;filtlf
  513. ;
  514.     if    addsp
  515.     cpi    cr
  516.     jnz    tabtst
  517.     lda    crflg
  518.     ora    a
  519.     mov    a,m
  520.     jz    crtest
  521.     call    more
  522.     dcr    l
  523.     mvi    a,' '
  524.     jmp    putchr
  525.     endif    ;addsp
  526. ;
  527. crtest:    CPI    CR    ;CARRIAGE RETURN ?
  528. ;
  529.     if    addlf or fltelf or addsp or addcr or addtab or addnsp
  530.     jnz    tabtst
  531.     mvi    a,true
  532.     sta    crflg
  533.     mov    a,m
  534.     cpi    cr
  535.     endif    ;addlf or fltelf or addsp or addcr or addtab or addnsp
  536. ;
  537.     if    tabrpl or spcrpl
  538.     jnz    tabtst
  539.     xra    a
  540.     sta    lincnt
  541.     sta    cmtflg
  542.     sta    quoflg
  543.     mov    a,m
  544.     cpi    cr
  545.     endif    ;tabrpl or spcrpl
  546. ;
  547.     JZ    PUTcrlf    ;YES GO WRITE IT
  548. tabtst:    CPI    TAB    ;TAB CHARACTER ?
  549. ;
  550.     if    spcrpl
  551.     cz    inccnt
  552.     mov    a,m
  553.     cpi    tab
  554.     jz    putcrlf    
  555.     endif    ;spcrpl
  556. ;
  557.     if    not (tabrpl or spcrpl)
  558.     JZ    PUTCHR    ;YES, GO WRITE IT
  559.     endif    ;not (tabrpl or spcrpl)
  560. ;
  561.     if    tabrpl
  562.     cz    tabset
  563.     mov    a,m
  564.     cpi    tab
  565.     jz    ignore
  566.     endif    ;tabrpl
  567. ;
  568.     if    fltesc
  569.     cpi    esc
  570.     jnz    nignor
  571.     mvi    a,true
  572.     sta    escflg
  573.     endif    ;fltesc
  574. ;
  575.     if    addlf
  576.     xra    a
  577.     sta    crflg
  578.     endif    ;addlf
  579. ;
  580. nignor:
  581.     if    not fltctl
  582.     mov    a,m
  583.     jmp    putcrlf
  584.     endif    ;not fltctl
  585. ;
  586. ;Ignore character and add one to ignore count
  587. ;
  588. IGNORE:    PUSH    H    ;SAVE INPUT BUFFER ADRS
  589.     LHLD    DCOUNT    ;GET DELETE COUNTER
  590.     INX    H    ;ADD ONE
  591.     SHLD    DCOUNT    ;SAVE NEW COUNT
  592.     POP    H    ;GET INPUT BUFFER ADRS BACK
  593.     JMP    TSTEND    ;IGNORE CHARACTER AND CONTINUE
  594. ;
  595. ;Pad last sector with EOFs
  596. ;
  597. padeof:    lhld    nxtout
  598.     call    sectst
  599.     jz    nopad
  600. padcnt:    mvi    m,eof
  601.     inx    h
  602.     call    sectst
  603.     jnz    padcnt
  604.     lxi    h,scinbf
  605.     inr    m
  606. nopad:    mvi    a,true
  607.     sta    finis
  608.     jmp    wrblock
  609. ;
  610. ;Check if end of output sector
  611. ;
  612. sectst:    mvi    a,0
  613.     cmp    l
  614.     rz
  615.     mvi    a,80h
  616.     cmp    l
  617.     ret
  618. ;
  619. ;Add one to acount
  620. ;
  621. more:    push    h
  622.     lhld    acount
  623.     inx    h
  624.     shld    acount
  625.     pop    h
  626.     ret
  627. ;
  628. ;Add count of spaces eliminated to dcount
  629. ;
  630.     if    spcrpl
  631. less:    push    h
  632.     lhld    dcount
  633.     lda    spccnt
  634. less2:    inx    h
  635.     dcr    a
  636.     jnz    less2
  637.     shld    dcount
  638.     pop    h
  639.     ret
  640.     endif    ;spcrpl
  641. ;
  642.     if    tabrpl
  643. tabset:    mvi    b,tablen
  644.     lda    lincnt
  645. tabagn:    sub    b
  646.     jnc    tabagn
  647.     cma
  648.     inr    a
  649.     inr    a
  650.     sta    tabcnt
  651.     mvi    a,true
  652.     sta    tabflg
  653.     ret
  654.     endif    ;tabrpl
  655. ;
  656.     if    spcrpl
  657. spcset:    mvi    a,true
  658.     sta    spcflg
  659.     xra    a
  660. spcst4:    inr    a    
  661.     sta    spccnt
  662.     lda    lincnt
  663.     inr    a
  664.     sta    lincnt
  665.     mvi    b,tablen
  666. tabagn:    sub    b
  667.     jz    spcst3
  668.     jnc    tabagn
  669.     inr    l
  670.     jz    readlp
  671. spcst5:    mov    a,m
  672.     cpi    tab
  673.     jz    spcst7
  674.     cpi    ' '
  675.     mvi    a,true
  676.     jnz    spcst3    ;put spaces
  677.     lda    spccnt
  678.     jmp    spcst4
  679. ;
  680. spcst2:    lda    dowflg
  681.     ora    a
  682.     jnz    dowrbf
  683.     jmp    spcst5
  684. ;
  685. spcst7:    call    inccnt
  686. spcst3:    cma
  687.     sta    tabflg
  688.     mvi    a,true
  689.     cma
  690.     sta    dowflg
  691. ;
  692. dowrbf:    lda    tabflg
  693.     ora    a
  694.     jz    space
  695.     xra    a
  696.     sta    tabflg
  697.     sta    dowflg
  698.     lda    spcflg
  699.     ora    a
  700.     mvi    a,false
  701.     sta    spcflg
  702.     jz    nosngl
  703.     lda    spccnt
  704.     cpi    1
  705.     mvi    a,' '
  706.     jz    putcrlf
  707.     call    more
  708. nosngl:    call    less
  709.     mvi    a,tab
  710.     jmp    putcrlf
  711. space:    dcr    l
  712.     lda    spccnt
  713.     dcr    a
  714.     sta    spccnt
  715.     jnz    moresp
  716.     xra    a
  717.     sta    spcflg
  718.     sta    dowflg
  719. moresp:    mvi    a,' '
  720.     jmp    putcrlf
  721. ;
  722. inccnt:    mvi    b,tablen
  723.     lda    lincnt
  724. tbagn2:    sub    b
  725.     jnc    tbagn2
  726.     cma
  727.     mov    b,a
  728.     lda    lincnt
  729.     add    b
  730.     inr    a
  731.     sta    lincnt
  732.     xra    a
  733.     sta    spcflg
  734.     ret
  735.     endif    ;spcrpl
  736. ;
  737. ;Write character to output buffer
  738. ;
  739. putchr:    
  740. ;
  741.     if    addlf or fltelf or addsp or addcr or addtab or addnsp
  742.     push    psw
  743.     xra    a
  744.     sta    crflg
  745.     pop    psw
  746.     endif    ;addlf or fltelf or addsp or addcr or addtab or addnsp
  747. ;
  748.     if    addnsp
  749.     push    psw
  750.     mvi    a,numspc
  751.     sta    spccnt
  752.     pop    psw
  753.     endif    ;addnsp
  754. ;
  755.     if    tabrpl or spcrpl
  756.     push    psw
  757.     lda    lincnt
  758.     inr    a
  759.     sta    lincnt
  760.     pop    psw
  761.     endif    ;tabrpl or spcrpl
  762. ;
  763.     if    fltesc
  764.     lda    escflg
  765.     ora    a        ;is it zero?
  766.     mov    a,m        ;now get the character back
  767.     jz    putcrlf        ;non-zero if prev char was ESC
  768.     xra    a
  769.     sta    escflg        ;so reset escflg
  770.     jmp    ignore        ;and igone the esc
  771.     endif    ;fltesc
  772.  
  773. ;
  774. putcrlf:
  775.     PUSH    H    ;SAVE INPUT BUFFER ADRS
  776.     lhld    nxtout
  777.     mov    m,a
  778.     inx    h
  779.     shld    nxtout
  780.     call    sectst
  781.     jnz    secnic
  782.     lda    scinbf
  783.     inr    a
  784.     sta    scinbf
  785.     cpi    bsize*8
  786.     jz    wrblock
  787. secnic:    POP    H    ;GET INPUT BUFFER ADRS BACK
  788. ;
  789. TSTEND:    INR    L    ;DONE WITH SECTOR?
  790.     JNZ    WRDLOP    ;NO, GET ANOTHER BYTE
  791.     JMP    READLP    ;GO GET ANOTHER SECTOR
  792. ;
  793. ;Write memory buffer to output file
  794. ;
  795. wrblock:
  796.     lda    scinbf
  797.     ora    a
  798.     jz    tdone
  799.     mov    c,a
  800.     lxi    d,buffer
  801. dkwrlp:    push    d
  802.     push    b
  803.     mvi    c,stdma
  804.     call    bdos
  805.     lxi    d,fcb2
  806.     mvi    c,write
  807.     call    bdos
  808.     pop    b
  809.     pop    d
  810.     ora    a
  811.     jnz    wrerr
  812.     lxi    h,80h
  813.     dad    d
  814.     xchg
  815.     dcr    c
  816.     jnz    dkwrlp
  817.     lda    finis
  818.     ora    a
  819.     jnz    tdone
  820.     xra    a
  821.     sta    scinbf
  822.     lxi    h,buffer
  823.     shld    nxtout
  824.     jmp    secnic
  825. ;
  826. wrerr:    call    erxit
  827.     DB    '++ OUTPUT FILE WRITE ERROR, DISK FULL ++$'
  828. ;
  829. ;Transfer is done - close destination file
  830. ;
  831. TDONE:    lxi    d,fcb2
  832.     mvi    c,close
  833.     call    bdos
  834. ;
  835. ;Rename files
  836. ;
  837.     if    renfil
  838.     xra    a
  839.     sta    fcb+16
  840.     sta    fcb2+16
  841.     lxi    d,fcb+16
  842.     lxi    h,fcb
  843.     mvi    b,12
  844.     call    move
  845.     lxi    d,fcb2+17
  846.     lxi    h,fcb2+1
  847.     mvi    b,11
  848.     call    move
  849.     lxi    d,fcb+25
  850.     lxi    h,bakftp
  851.     mvi    b,3
  852.     call    move
  853.     lxi    d,fcb2+25
  854.     lxi    h,fcb+9
  855.     mvi    b,3
  856.     call    move
  857.     lxi    d,fcb+16
  858.     mvi    c,erase
  859.     call    bdos
  860.     xra    a
  861.     sta    fcb+16
  862.     lxi    d,fcb
  863.     mvi    c,rename
  864.     call    bdos
  865.     lxi    d,fcb2
  866.     mvi    c,rename
  867.     call    bdos
  868.     endif    ;renfil
  869. ;    
  870. ;Output messages to operator and exit
  871. ;
  872.     CALL    ILPRT    ;PRINT:
  873.     DB    'Function complete:',cr,lf,0
  874.     if    tabrpl or fltesc or spcrpl or filtlf or fltelf or fltctl
  875.     LHLD    DCOUNT    ;GET DELETED CHAR COUNT
  876.     CALL    DECOUT    ;PRINT IT
  877.     call    ilprt
  878.     endif    ;tabrpl or fltesc or spcrpl or filtlf or fltelf or fltctl
  879.     if    fltctl
  880.     DB    ' bytes '
  881.     endif    ;fltctl
  882.     if    (tabrpl or fltesc or spcrpl or filtlf or fltelf) and fltctl
  883.     db    'including'
  884.     endif    ;(tabrpl or fltesc or spcrpl or filtlf or fltelf) and fltctl
  885.     if    tabrpl
  886.     db    ' TABs '
  887.     endif    ;tabrpl
  888.     if    tabrpl and filtlf
  889.     db    'and'
  890.     endif    ;tabrpl and filtlf
  891.     if    filtlf or fltelf
  892.     db    ' LFs '
  893.     endif    ;filtlf or fltelf
  894.     if    spcrpl
  895.     db    ' spaces '
  896.     endif    ;spcrpl
  897.     if    fltesc
  898.     db    ' single characters following ESC '
  899.     endif    ;fltesc
  900.     if    tabrpl or spcrpl or filtlf or fltelf or fltctl or fltesc
  901.     db    'deleted',cr,lf,0
  902.     endif    ;tabrpl or spcrpl or filtlf or fltelf or fltctl or fltesc
  903.     if    addlf or addsp or addcr or tabrpl or addtab or addnsp or spcrpl
  904.     lhld    acount
  905.     call    decout
  906.     call    ilprt
  907.     endif    ;addlf or addsp or addcr or tabrpl or addtab
  908.         ;or addnsp or spcrpl
  909.     if    tabrpl or addnsp or addsp
  910.     db    ' spaces added',cr,lf,0
  911.     endif    ;tabrpl or addnsp or addsp
  912.     if    spcrpl or addtab
  913.     db    ' TABs added',cr,lf,0
  914.     endif    ;spcrpl or addtab
  915.     if    addlf
  916.     db    ' LFs added',cr,lf,0
  917.     endif    ;addlf
  918.     if    addcr
  919.     db    ' CRs added',cr,lf,0
  920.     endif    ;addcr
  921.     call    ilprt
  922.     db    'Last sector padded with EOFs',cr,lf,0
  923.     jmp    wboot
  924. ;
  925. ;Erase the incomplete output file, then exit
  926. ;
  927. ERXIT:    lxi    d,fcb2
  928.     mvi    c,close
  929.     call    bdos
  930.     lxi    d,fcb2
  931.     mvi    c,erase
  932.     call    bdos
  933. ;
  934. ;Print message then exit to CP/M warm boot
  935. ;
  936. EXIT:    POP    D    ;GET MSG ADRS
  937.     MVI    C,PRINT    ;PRINT MESSAGE
  938.     CALL    BDOS
  939.     CALL    ILPRT    ;PRINT CRLF
  940.     DB    CR,LF,0
  941.     JMP    WBOOT    ;ASSURES UPDATE OF BIT MAP
  942. ;
  943. ;Print illegal destination drive message
  944. ;
  945. wrgdest:
  946.     call    exit
  947.     db    '++ ILLEGAL DESTINATION DRIVE ++$'
  948. ;
  949. ;Inline print routine - prints string pointed to
  950. ;by stack until a zero is found.  Returns to caller
  951. ;at next address after the zero terminator.
  952. ;
  953. ILPRT:    XTHL        ;SAVE HL, GET MSG ADRS
  954. ;
  955. ILPLP:    MOV    A,M    ;GET CHAR
  956.     CALL    TYPE    ;OUTPUT IT
  957.     INX    H    ;POINT TO NEXT
  958.     MOV    A,M    ;TEST
  959.     ORA    A    ;..FOR END
  960.     JNZ    ILPLP
  961.     XTHL        ;RESTORE HL, RET ADDR
  962.     RET        ;RET PAST MSG
  963. ;
  964. ;Send character in A register to console
  965. ;
  966. TYPE:    PUSH    B
  967.     PUSH    D
  968.     PUSH    H
  969.     MOV    E,A    ;CHAR TO E FOR CP/M
  970.     MVI    C,WRCON    ;WRITE TO CONSOLE
  971.     CALL    BDOS
  972.     POP    H
  973.     POP    D
  974.     POP    B
  975.     RET
  976. ;
  977. ;Decimal output - print HL as decimal
  978. ;number with leading zero suppression
  979. ;
  980. DECOUT:    PUSH    B
  981.     PUSH    D
  982.     PUSH    H
  983.     LXI    B,-10
  984.     LXI    D,-1
  985. ;
  986. DECOU2:    DAD    B
  987.     INX    D
  988.     JC    DECOU2
  989.     LXI    B,10
  990.     DAD    B
  991.     XCHG
  992.     MOV    A,H
  993.     ORA    L
  994.     CNZ    DECOUT
  995.     MOV    A,E
  996.     ADI    '0'
  997.     CALL    TYPE
  998.     POP    H
  999.     POP    D
  1000.     POP    B
  1001.     RET
  1002. ;
  1003. move:    mov    a,m
  1004.     stax    d
  1005.     inx    h
  1006.     inx    d
  1007.     dcr    b
  1008.     jnz    move
  1009.     ret
  1010. ;
  1011. ;Output file control bytes
  1012. ;
  1013. fcb2:    db    '         '
  1014. ;         ^^^^^^^^^    ;9 bytes
  1015. ftype:
  1016.     if    addlf
  1017.     db    'ALF'
  1018.     endif    ;addlf
  1019.     if    fltelf
  1020.     db    'FEL'
  1021.     endif    ;fltelf
  1022.     if    filtlf and (not addsp) and (not tabrpl)
  1023.     db    'FLF'
  1024.     endif    ;filtlf and (not addsp) and (not tabrpl)
  1025.     if    addsp and (not filtlf) and (not tabrpl)
  1026.     db    'ASP'
  1027.     endif    ;addsp and (not filtlf) and (not tabrpl)
  1028.     if    filtlf and addsp and (not tabrpl)
  1029.     db    'SFL'
  1030.     endif    ;filtlf and addsp and (not tabrpl)
  1031.     if    fltesc
  1032.     db    'FES'
  1033.     endif    ;fltesc
  1034.     if    addcr
  1035.     db    'ACR'
  1036.     endif    ;addcr
  1037.     if    tabrpl and (not filtlf) and (not addsp)
  1038.     db    'RTB'
  1039.     endif    ;tabrpl and (not filtlf) and (not addsp)
  1040.     if    tabrpl and (not filtlf) and addsp
  1041.     db    'SRT'
  1042.     endif    ;tabrpl and (not filtlf) and addsp
  1043.     if    tabrpl and filtlf and (not addsp)
  1044.     db    'FLT'
  1045.     endif    ;tabrpl and filtlf and (not addsp)
  1046.     if    tabrpl and filtlf and addsp
  1047.     db    'FBB'
  1048.     endif    ;tabrpl and filtlf and addsp
  1049.     if    addtab
  1050.     db    'ATB'
  1051.     endif    ;addtab
  1052.     if    addnsp
  1053.     db    'ANS'
  1054.     endif    ;addnsp
  1055.     if    spcrpl and (not fltasm)
  1056.     db    'RSP'
  1057.     endif    ;spcrpl and (not fltasm)
  1058.     if    fltasm
  1059.     db    'FSM'
  1060.     endif    ;fltasm
  1061.     db    0,0,0,0,0,0,0,0,0,0,0,0
  1062.     db    0,0,0,0,0,0,0,0,0,0,0,0
  1063.     db    0,0,0
  1064. ;
  1065. lincnt:    db    0
  1066. tabcnt:    db    0
  1067. scinbf: db    0
  1068. finis:    db    false
  1069. spccnt:    db    numspc
  1070. tabflg:    db    false
  1071. spcflg:    db    false
  1072. dowflg:    db    false
  1073. quoflg:    db    false
  1074. cmtflg:    db    false
  1075. escflg:    db    false
  1076. crflg:
  1077.     if    not (addsp or addnsp or addtab)
  1078.     db    false
  1079.     endif    ;not (addsp or addnsp or addtab)
  1080.     if    addsp or addnsp or addtab
  1081.     db    true
  1082.     endif    ;addsp or addnsp or addtab
  1083. nxtout:    dw    buffer
  1084. DCOUNT:    DW    0    ;DELETED CHARACTER COUNTER
  1085. acount:    dw    0    ;added character counter
  1086. bakftp:    db    'BAK'
  1087. fixftp:    db    'FIX'
  1088. padftp:    db    'PAD'
  1089.         DS    100    ;ROOM FOR STACK
  1090. STACK:        ds    2    ;STACK POINTER SET HERE
  1091. ;
  1092. ;Put write buffer on even page boundary
  1093. BUFFER    EQU    ($ and 0ff00h) + 100h    ;WRITE BUFFER STARTS HERE
  1094. ;
  1095.     END
  1096.