home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols200 / vol203 / ffynde.asm < prev    next >
Encoding:
Assembly Source File  |  1984-12-19  |  21.4 KB  |  1,332 lines

  1.  
  2. ;    ----------------------------------------------------------
  3. ;    FFYNDE.ASM is a variant of FYNDE.ASM in which a family of
  4. ;    files can be searched for many different keywords, which
  5. ;    are taken one at a time from an auxiliary file. Indices or
  6. ;    cross-reference listings are readily prepared by using it,
  7. ;    supposing that a previous pass has isolated the indexing
  8. ;    items and placed them in the auxiliary file. XREF.CNV can
  9. ;    be used for the initial pass.
  10. ;
  11. ;    Beware:
  12. ;        spaces count as part of patterns, especialy the
  13. ;        first ones: <file.ext  patt> has ONE space. So
  14. ;        does <file.ext patt >.
  15. ;
  16. ;        {?} requires at least ONE character.
  17. ;
  18. ;            FFYNDE.ASM  Copyright (C) 1984
  19. ;            Universidad Autonoma de Puebla
  20. ;
  21. ;    [Harold V. McIntosh, 20 August 1984]
  22. ;    ----------------------------------------------------------
  23.  
  24. HT    equ    09H        ;horizontal tab
  25. LF    equ    0AH        ;line feed
  26. CR    equ    0DH        ;carriage return
  27. KZ    equ    1AH        ;^Z
  28.  
  29. ;    Delimiters for the command line
  30.  
  31. LSQ    equ    '['        ;begin alternative list
  32. RSQ    equ    ']'        ;end alternative list
  33. LBR    equ    '{'        ;begin iterated expression
  34. RBR    equ    '}'        ;end iterated expression
  35. ORR    equ    '!'        ;separate alternatives
  36.  
  37. ;    Representatives of characters or classes.
  38.  
  39. TAB    equ    '_'        ;substitute for tab
  40. QUE    equ    '?'        ;represent any byte
  41. ALF    equ    '@'        ;represent any alphanumeric
  42.  
  43. ;    CP/M and other locations and parameters
  44.  
  45. cfcb    equ    005CH        ;CP/M's file control block
  46. csiz    equ    0080H        ;CP/M's record size
  47. cbuf    equ    0080H        ;CP/M's record buffer
  48. ksiz    equ    26        ;sector capacity of IN buffer
  49. isiz    equ    ksiz*128
  50. hsiz    equ    257        ;max characters in Huffman code
  51.  
  52. ;    ------------
  53.     org    100H
  54. ;    ------------
  55.  
  56. begn:    lxi    sp,stak
  57.     lda    cfcb+1        ;file name
  58.     cpi    ' '
  59.     jnz    ntut
  60.     lxi    h,M1        ;tutorial
  61. ferm:    call    mssg        ;message to console
  62.     jmp    0000
  63.  
  64. ntut:    lxi    h,M2        ;signon message
  65.     call    xref        ;message to .XRF file
  66.     call    mssg        ;message to console
  67.  
  68.     mvi    c,12
  69.     lxi    d,cfcb        ;CP/M's file control block
  70.     lxi    h,sfam        ;search family
  71.     call    miuc        ;block move
  72.  
  73.     mvi    c,12
  74.     lxi    d,cfcb+16    ;CP/M's file control block
  75.     lxi    h,kfil        ;keyword FCB
  76.     call    miuc        ;block move
  77.     lxi    b,0015H        ;21 0's
  78.     call    fiuc        ;block fill
  79.     lxi    h,kfil+9    ;keyword FCB
  80.     mov    a,m
  81.     cpi    ' '
  82.     jnz    kext
  83.     mvi    m,'S'
  84.     inx    h
  85.     mvi    m,'Y'
  86.     inx    h
  87.     mvi    m,'M'
  88.  
  89. kext:    mvi    c,9
  90.     lxi    d,cfcb+16    ;CP/M's file control block
  91.     lxi    h,xfil        ;.XRF FCB
  92.     call    miuc        ;block move
  93.     mvi    m,'X'
  94.     inx    h
  95.     mvi    m,'R'
  96.     inx    h
  97.     mvi    m,'F'
  98.     inx    h
  99.     lxi    b,0015        ;21 0's
  100.     call    fiuc        ;block fill
  101.  
  102.     lxi    h,cbuf        ;CP/M's record buffer
  103.     mov    e,m
  104.     mvi    d,0
  105.     inx    d
  106.     xchg
  107.     dad    d
  108.     mvi    m,0
  109.     xchg
  110.  
  111. ;    Skip any initial spaces.
  112.  
  113. ispa:    inx    h
  114.     mov    a,m
  115.     ora    a
  116.     jz    X029C
  117.     cpi    ' '
  118.     jz    ispa
  119.  
  120. ;    Skip over file name.
  121.  
  122. sfil:    inx    h
  123.     mov    a,m
  124.     ora    a
  125.     jz    X029C
  126.     cpi    ' '
  127.     jnz    sfil
  128.  
  129. ;    skip over blanks
  130.  
  131. sblk:    inx    h
  132.     mov    a,m
  133.     ora    a
  134.     jz    X029C
  135.     cpi    ' '
  136.     jz    sblk
  137.  
  138. ;    skip keyfile name
  139.  
  140. skey:    inx    h
  141.     mov    a,m
  142.     ora    a
  143.     jz    hedr        ;no header desired
  144.     cpi    ' '
  145.     jnz    skey
  146.     inx    h        ;pass over last space
  147.  
  148. ;    Read header description.
  149.  
  150. hedr:    call    bala        ;check balance of [], {}.
  151.     call    nula        ;check for null alternatives
  152.     lxi    d,patt        ;command line pattern
  153.     call    muve        ;copy & semicompile cmd line
  154.  
  155. ;    Open keyword file.
  156.  
  157.     mvi    c,15        ;(0F) open file
  158.     lxi    d,kfil        ;keyword FCB
  159.     call    0005        ; - B D O S -
  160.     inr    a
  161.     jnz    okey
  162.     lxi    h,nkey        ;'cannot open keyword file'
  163.     jmp    ferm        ;final (error) message
  164.  
  165. ;    Create crossreference file.
  166.  
  167. okey:    mvi    c,17        ;(11) search for file
  168.     lxi    d,xfil        ;.XRF FCB
  169.     call    0005        ; - B D O S -
  170.     inr    a
  171.     jz    cxrf
  172.     lxi    h,yexi        ;'file already exists'
  173.     jmp    ferm        ;final (error) message
  174.  
  175. cxrf:    mvi    c,22        ;(16) create file
  176.     lxi    d,xfil        ;.XRF FCB
  177.     call    0005        ; - B D O S -
  178.     inr    a
  179.     jnz    gogo
  180.     lxi    d,nxrf        ;'can''t open file'
  181.     jmp    ferm        ;final (error) message
  182.  
  183. gogo:    mvi    c,4
  184.     lxi    d,lzer        ;zero line for counter
  185.     lxi    h,ktot        ;keyword total
  186.     call    miuc        ;block move
  187.  
  188.     lxi    h,csiz        ;CP/M's record size
  189.     shld    xctr        ;crossreference counter
  190.     lxi    h,xbuf        ;crossreference buffer
  191.     shld    xptr        ;crossreference pointer
  192.     lxi    h,0000
  193.     shld    kctr        ;keyword counter
  194.     shld    lapo        ;label pointer
  195.     lxi    h,patt        ;command line pattern
  196.     mov    a,m
  197.     ora    a
  198.     jz    golu
  199.     shld    lapo        ;label pointer
  200.  
  201. golu:    lxi    d,kwrd        ;keyword pattern
  202.     lxi    h,keyr        ;raw keyword
  203.     call    meuv        ;read & semicompile keyword
  204.     cpi    01AH
  205.     jz    golv
  206.     xra    a
  207.     stax    d
  208.     mov    m,a
  209.     sta    enth        ;search-again counter
  210.     lxi    h,kwdi        ;'keyword is'
  211.     call    xref        ;message to .XRF file
  212.     call    mssg        ;message to console
  213.     lxi    h,crlf
  214.     call    xref        ;message to .XRF file
  215.     call    mssg        ;message to console
  216.     call    ongo
  217.     lxi    h,ktot+3    ;total # keywords
  218.     call    inco        ;increment counter
  219.     jmp    golu
  220.  
  221. golv:    lxi    h,ktot        ;'keyword totals'
  222.     call    xref        ;message to .XRF file
  223.     call    mssg        ;message to console
  224.     call    zxrf
  225.     jmp    0000
  226.  
  227. ongo:    mvi    c,4
  228.     lxi    d,lzer        ;zero line for counter
  229.     lxi    h,dtot        ;total throughout disk
  230.     call    miuc        ;block move
  231.  
  232. ;    Scan the directory for file names.
  233.  
  234. scan:    mvi    c,26        ;(1A) set DMA address
  235.     lxi    d,cbuf        ;CP/M's record buffer
  236.     call    0005        ; - B D O S -
  237.  
  238.     lxi    h,cfcb+12
  239.     mvi    m,00
  240.  
  241.     mvi    c,17        ;(11) search once
  242.     lxi    d,sfam        ;search family
  243.     call    0005        ; - B D O S -
  244.  
  245.     lxi    h,enth        ;search-again counter
  246.     inr    m
  247.     mov    c,m
  248. fnth:    inr    a
  249.     jz    done        ;we're all done
  250.     dcr    c
  251.     jz    this
  252.     push    b
  253.     mvi    c,18        ;(12) search again
  254.     lxi    d,sfam        ;search family
  255.     call    0005        ; - B D O S -
  256.     pop    b
  257.     jmp    fnth
  258.  
  259. ;    We're all done.
  260.  
  261. done:    lxi    h,dtot        ;total throughout disk
  262.     call    xref        ;message to .XRF file
  263.     jmp    mssg        ;message to console
  264.  
  265. ;    A prospective file has been located
  266.  
  267. this:    dcr    a
  268.     ani    03
  269.     add    a
  270.     add    a
  271.     add    a
  272.     add    a
  273.     add    a
  274.     adi    81H
  275.     mov    e,a
  276.     mvi    d,00
  277.     mvi    c,12
  278.     lxi    h,cfcb+1    ;CP/M's file control block
  279.     call    miuc        ;block move
  280.  
  281.     lxi    h,cfcb+9    ;CP/M's file control block
  282.     call    dcom        ;disregard .COM files
  283.     jz    scan
  284.     lxi    h,cfcb+9    ;CP/M's file control block
  285.     call    dcmd        ;disregard .CMD files
  286.     jz    scan
  287.     lxi    h,cfcb+9    ;CP/M's file control block
  288.     call    dxrf        ;disregard .XRF files
  289.     jz    scan
  290.  
  291. ;    Open the file, check for squeezing.
  292.  
  293.     mvi    c,15        ;(0F) open file
  294.     lxi    d,cfcb        ;CP/M's FCB
  295.     call    0005        ; - B D O S -
  296.     inr    a
  297.     jz    0000        ;quit [without message]
  298.     xra    a
  299.     sta    cfcb+32
  300.     sta    cfcb+32        ;block pointer
  301.     sta    dens        ;z/nz=un/squeezed
  302.     sta    mult        ;repeat factor
  303.     lxi    h,0000
  304.     shld    ictr        ;input counter
  305.  
  306.     lxi    h,cfcb+10    ;CP/M's file control block
  307.     mov    a,m
  308.     cpi    'Q'
  309.     jnz    nsqz
  310.     call    gbyt        ;fetch one byte
  311.     cpi    076H
  312.     jnz    nsqz
  313.     call    gbyt        ;fetch one byte
  314.     cpi    0FFH
  315.     jnz    nsqz
  316.     lxi    h,dens        ;z/nz=un/squeezed
  317.     mvi    m,0FFH
  318.     call    rwor        ;fetch word
  319.  
  320. ;    unsqueezed file name
  321.  
  322.     lxi    b,200CH        ;twelve spaces
  323.     lxi    h,uzfn        ;unsqueezed file's name
  324.     call    fiuc        ;block fill
  325.  
  326.     mvi    b,8
  327.     lxi    d,uzfn        ;unsqueezed file's name
  328. luup:    call    gbyt        ;fetch one byte
  329.     ora    a
  330.     jz    luut
  331.     cpi    '.'
  332.     jz    luuw
  333.     stax    d
  334.     inx    d
  335.     dcr    b
  336.     jnz    luup
  337. luuz:    call    gbyt
  338.     ora    a
  339.     jz    luut
  340.     cpi    '.'
  341.     jnz    luuz
  342. luuw:    mvi    b,3
  343.     lxi    d,uzfn+8
  344.     stax    d
  345.     inx    d
  346. luur:    call    gbyt
  347.     ora    a
  348.     jz    luut
  349.     stax    d
  350.     inx    d
  351.     dcr    b
  352.     jnz    luur
  353. luus:    call    gbyt
  354.     ora    a
  355.     jnz    luus
  356.  
  357. luut:    lxi    h,uzfn+9    ;unsqueezed FCB
  358.     call    dcom        ;disregard .COM files
  359.     jz    scan
  360.     lxi    h,uzfn+9    ;unsqueezed FCB
  361.     call    dcmd        ;disregard .CMD files
  362.     jz    scan
  363.     lxi    h,cfcb+9    ;unsqueezed FCB
  364.     call    dxrf        ;disregard .XRF files
  365.     jz    scan
  366.  
  367.  
  368. ;    load code directory
  369.  
  370. ldic:    call    rwor        ;fetch word
  371.     lxi    b,hsiz
  372.     mov    a,c
  373.     sub    l
  374.     mov    a,b
  375.     sbb    h
  376.     jnc    ldii
  377.     lxi    h,M8        ;'code table won't fit'
  378.     call    mssg        ;message to console
  379.     jmp    scan
  380.  
  381. ldii:    dad    h
  382.     dad    h
  383.     mov    c,l
  384.     mov    b,h
  385.     lxi    d,code        ;code table
  386. ldij:    call    gbyt        ;fetch one byte
  387.     stax    d
  388.     inx    d
  389.     dcx    b
  390.     mov    a,c
  391.     ora    b
  392.     jnz    ldij
  393.  
  394.     lxi    h,roco        ;rotation count
  395.     mvi    m,1
  396.  
  397. nsqz:    mvi    c,4
  398.     lxi    d,lzer        ;zero line for counter
  399.     lxi    h,lnum        ;'line number'
  400.     call    miuc        ;block move
  401.  
  402.     mvi    c,4
  403.     lxi    d,lzer        ;zero line for counter
  404.     lxi    h,ftot        ;'file total'
  405.     call    miuc        ;block move
  406.  
  407.     mvi    c,8
  408.     lxi    d,cfcb+1    ;file name
  409.     lxi    h,fnam        ;'file name'
  410.     call    miuc        ;block move
  411.  
  412.     mvi    c,3
  413.     lxi    d,0065H        ;extension
  414.     lxi    h,fext        ;'file extension'
  415.     call    miuc        ;block move
  416.  
  417.     lxi    h,fhed        ;'header ----> FILE'
  418.     call    xref        ;message to .XRF file
  419.     call    mssg        ;message to console
  420.     lda    dens
  421.     ora    a
  422.     jz    sixs
  423.     lxi    h,hesq        ;'[original]'
  424.     call    xref        ;message to .XRF file
  425.     call    mssg        ;message to console
  426.  
  427. sixs:    lxi    b,2006H        ;six spaces
  428.     lxi    h,llbl
  429.     call    fiuc        ;block fill
  430.  
  431. X01C8:    lxi    h,lnum+3    ;line number
  432.     call    inco        ;increment counter
  433.     lxi    h,lbuf        ;line buffer
  434.     mvi    b,0FFH
  435. X01E0:    inr    b
  436.     jm    X01FD
  437.     push    b
  438.     push    h
  439.     call    inch        ;char from big bffr to line bffr
  440.     pop    h
  441.     pop    b
  442.     mov    m,a
  443.     inx    h
  444.     cpi    KZ
  445.     jnz    X01E8
  446.     lxi    h,ftot
  447.     call    xref        ;message to .XRF file
  448.     call    mssg        ;message to console
  449.     jmp    scan
  450.  
  451. X01E8:    cpi    LF
  452.     jnz    X01E0
  453.     jmp    X0202
  454.  
  455. X01FD:    mvi    m,CR
  456.     inx    h
  457.     mvi    m,LF
  458.     inx    h
  459.  
  460. ;    Check console for termination request. If one
  461. ;    is present, clear it out before leaving.
  462.  
  463. X0202:    mvi    m,00        ;guarantee right hand fence
  464.  
  465.     mvi    c,11        ;(0B) console status
  466.     call    0005        ; - B D O S -
  467.     ora    a
  468.     jz    culi
  469.  
  470.     mvi    c,1        ;(01) read console
  471.     call    0005        ; - B D O S -
  472.     cpi    03H        ;^C
  473.     jnz    skpf
  474.  
  475.     mvi    c,19        ;(13) delete file
  476.     lxi    d,xfil        ;.XRF FCB
  477.     call    0005        ; - B D O S -
  478.     lxi    h,M4        ;"search terminated"
  479.     jmp    ferm        ;final (error) message
  480.  
  481. skpf:    lxi    h,M5        ;"remainder of file skipped"
  482.     call    xref        ;message to .XRF file
  483.     call    mssg        ;message to console
  484.     jmp    scan
  485.  
  486. ;    Scan the current line.
  487. ;    First see if it is labelled.
  488.  
  489. culi:    lhld    lapo        ;label pointer
  490.     mov    a,h
  491.     ora    l
  492.     jz    X0217        ;no label requested
  493.     xchg
  494.     lxi    h,lbuf
  495.     call    chek
  496.     jnz    X0217        ;label not found
  497.     push    h
  498.     lxi    b,2006H        ;six spaces
  499.     lxi    h,llbl
  500.     call    fiuc        ;block fill
  501.     pop    h
  502.     lxi    d,llbl+5
  503.     mvi    c,6
  504. didl:    dcx    h
  505.     mov    a,m
  506.     cpi    HT        ;ignore tabs in text
  507.     jz    didl
  508.     cpi    ' '        ;quit at head of line
  509.     jc    dido
  510.     stax    d
  511.     dcx    d
  512.     dcr    c
  513.     jnz    didl
  514. dido:    mvi    c,4
  515.     lxi    d,lzer        ;zero line for counter
  516.     lxi    h,lnum        ;line number
  517.     call    miuc        ;block move
  518.  
  519. ;    Now look for the pattern
  520.  
  521. X0217:    lxi    h,lbuf        ;line buffer
  522. X021A:    lxi    d,kwrd        ;keyword pattern
  523.     push    h
  524.     call    chek
  525.     pop    h
  526.     jz    X0263
  527.     mov    a,m
  528.     cpi    CR
  529.     jz    X01C8        ;increment l.c. at X026A
  530.     inx    h
  531.     jmp    X021A
  532.  
  533. ;    Pattern matches, so type label & line containing it
  534.  
  535. X0263:    lxi    h,llbl        ;line label
  536.     call    xref        ;message to .XRF file
  537.     call    mssg        ;message to console
  538.     lxi    h,lbuf        ;line buffer
  539.     call    xref        ;message to .XRF file
  540.     call    mssg        ;message to console
  541.     lxi    h,ftot+3
  542.     call    inco        ;increment counter
  543.     lxi    h,dtot+3    ;total throughout disk
  544.     call    inco        ;increment counter
  545.     jmp    X01C8        ;increment l.c. at X026A
  546.  
  547. ;    Increment ASCII counter at (HL-3).
  548.  
  549. inco:    mov    a,m
  550.     ori    30H
  551.     inr    a
  552.     mov    m,a
  553.     cpi    ':'
  554.     rnz
  555.     mvi    m,'0'
  556.     dcx    h
  557.     jmp    inco        ;increment counter
  558.  
  559. ;    Memory to console
  560.  
  561. mssg:    mov    e,m
  562.     inx    h
  563.     push    h
  564.     mvi    c,2        ;(02) write console
  565.     call    0005        ; - B D O S -
  566.     pop    h
  567.     mov    a,m
  568.     ora    a
  569.     jnz    mssg        ;message to console
  570.     ret
  571.  
  572. X029C:    lxi    h,M3        ;"bad pattern"
  573.     call    ferm        ;final (error) message
  574.  
  575. ;    decode next character
  576.  
  577. dnch:    lxi    h,code        ;code table
  578. dncr:    call    rbit
  579.     jnc    dncs
  580.     inx    h
  581.     inx    h
  582. dncs:    mov    e,m
  583.     inx    h
  584.     mov    d,m
  585.     mov    a,d
  586.     cpi    0FEH
  587.     jz    dnct
  588.     ora    a
  589.     jp    dncu
  590.     mov    a,e
  591.     cma
  592.     stc
  593.     cmc
  594.     ret
  595.  
  596. dnct:    stc
  597.     ret
  598.  
  599. ;    Calculate <code>+4*<offset>.
  600.  
  601. dnncu:    lxi    h,code        ;code table
  602.     dad    d
  603.     dad    d
  604.     dad    d
  605.     dad    d
  606.     jmp    dncr
  607.  
  608. ;    read one bit at a time
  609.  
  610. rbit:    push    h
  611.     lxi    h,roco        ;rotation count
  612.     dcr    m
  613.     jnz    rbiu
  614.     mvi    m,8
  615.     call    gbyt        ;fetch one byte
  616.     sta    roby        ;rotating byte
  617. rbiu:    lda    roby        ;rotating byte
  618.     rar
  619.     sta    roby        ;rotating byte
  620.     pop    h
  621.     ret
  622.  
  623. ;    read one word
  624.  
  625. rwor:    call    gbyt        ;fetch one byte
  626.     push    psw
  627.     call    gbyt        ;fetch one byte
  628.     pop    h
  629.     mov    l,h
  630.     mov    h,a
  631.     ret
  632.  
  633. ;    Fetch the next byte. The input buffer will be refreshed if it
  634. ;    is necessary. For normal files, one byte will be extracted from
  635. ;    the input buffer; for squeezed files, one byte will be decoded
  636. ;    from the incoming bit stream and subtracted from the checksum.
  637.  
  638. inch:    lda    dens        ;z/nz = un/squeezed
  639.     ora    a
  640.     jz    gbyt        ;fetch one byte
  641.     lda    mult        ;repeat factor
  642.     ora    a
  643.     jz    gusq
  644.     dcr    a
  645.     sta    mult        ;repeat factor
  646.     lda    lach        ;last character read
  647.     ret
  648.  
  649. gusq:    call    dnch
  650.     jnc    guss
  651.     mvi    a,1AH
  652.     ret
  653.  
  654. guss:    cpi    090H
  655.     jz    gusu
  656.     sta    lach        ;last character read
  657.     ret
  658.  
  659. gusu:    cal    dnch
  660.     ora    a
  661.     jnz    gusv
  662.     mvi    a,090H
  663.     ret
  664.  
  665. gusv:    dcr    a
  666.     dcr    a
  667.     sta    mult        ;repeat factor
  668.     lda    lach        ;last character read
  669.     ret
  670.  
  671. ;    unsqueezed (normal) text
  672.  
  673. gbyt:    lhld    ictr        ;input counter
  674.     mov    a,h
  675.     ora    l
  676.     cz    indi        ;disk to IN area
  677.     lhld    ictr        ;input counter
  678.     dcx    h
  679.     shld    ictr        ;input counter
  680.     lhld    iptr        ;input pointer
  681.     mov    a,m
  682.     inx    h
  683.     shld    iptr        ;input pointer
  684.     ret
  685.  
  686. indi:    mvi    b,ksiz
  687.     lxi    h,isiz
  688.     shld    ictr        ;input counter
  689.     lxi    h,ibuf        ;input buffer
  690.     shld    iptr        ;input pointer
  691. indd:    mvi    m,KZ
  692.     push    h
  693.     push    b
  694.     xchg
  695.     mvi    c,26        ;(1A) set DMA address
  696.     call    0005        ; - B D O S -
  697.     lxi    d,cfcb        ;CP/M's file control block
  698.     mvi    c,20        ;(14) read one record
  699.     call    0005        ; - B D O S -
  700.     pop    b
  701.     pop    h
  702.     ora    a
  703.     rnz
  704.     dcr    b
  705.     rz
  706.     lxi    d,csiz        ;CP/M's record size
  707.     dad    d
  708.     jmp    indd
  709.  
  710. ;    Fetch next keyword byte.
  711.  
  712. gkey:    push    h
  713.     lhld    kctr        ;keyword counter
  714.     mov    a,h
  715.     ora    l
  716.     cz    kndi        ;disk to IN area
  717.     lhld    kctr        ;keyword counter
  718.     dcx    h
  719.     shld    kctr        ;keyword counter
  720.     lhld    kptr        ;input pointer
  721.     mov    a,m
  722.     inx    h
  723.     shld    kptr        ;input pointer
  724.     pop    h
  725.     ret
  726.  
  727. kndi:    lxi    h,csiz        ;CP/M's record size
  728.     shld    kctr        ;keyword counter
  729.     lxi    h,kbuf        ;input buffer
  730.     shld    kptr        ;input pointer
  731.     mvi    m,KZ
  732.     push    h
  733.     push    d
  734.     push    b
  735.     xchg
  736.     mvi    c,26        ;(1A) set DMA address
  737.     call    0005        ; - B D O S -
  738.     lxi    d,kfil        ;keyword FCB
  739.     mvi    c,20        ;(14) read one record
  740.     call    0005        ; - B D O S -
  741.     pop    b
  742.     pop    d
  743.     pop    h
  744.     ora    a
  745.     ret
  746.  
  747. ;    Send line to .XRF FCB.
  748.  
  749. xref:    push    h
  750. xreg:    mov    a,m
  751.     ora    a
  752.     jz    xreh
  753.     inx    h
  754.     push    h
  755.     call    wxrf
  756.     pop    h
  757.     jmp    xreg        ;message to .XRF file
  758. xreh:    pop    h
  759.     ret
  760.  
  761. ;    Write next crossreference byte.
  762.  
  763. wxrf:    push    psw
  764.     lhld    xctr        ;crossreference counter
  765.     mov    a,h
  766.     ora    l
  767.     cz    xndi        ;disk to IN area
  768.     lhld    xctr        ;crossreference counter
  769.     dcx    h
  770.     shld    xctr        ;crossreference counter
  771.     lhld    xptr        ;crossreference pointer
  772.     pop    psw
  773.     mov    m,a
  774.     inx    h
  775.     shld    xptr        ;crossreference pointer
  776.     ret
  777.  
  778. xndi:    lxi    h,csiz        ;CP/M's record size
  779.     shld    xctr        ;crossreference counter
  780.     lxi    h,xbuf        ;crossreference buffer
  781.     shld    xptr        ;crossreference pointer
  782.     push    h
  783.     push    b
  784.     xchg
  785.     mvi    c,26        ;(1A) set DMA address
  786.     call    0005        ; - B D O S -
  787.     lxi    d,xfil        ;.XRF FCB
  788.     mvi    c,21        ;(15) write one record
  789.     call    0005        ; - B D O S -
  790.     cpi    00
  791.     lxi    h,xwre        ;'can''t write'
  792.     jnz    ferm        ;final (error) message
  793.     pop    b
  794.     pop    h
  795.     ora    a
  796.     ret
  797.  
  798. ;    Close crossreference file.
  799.  
  800. zxrf:    lhld    xctr
  801.     xchg
  802.     mov    a,e
  803.     ora    d
  804.     jz    clos
  805.     lhld    xptr        ;crossreference pointer
  806. zxrg:    mvi    m,01AH        ;^Z
  807.     inx    h
  808.     dcx    d
  809.     mov    a,e
  810.     ora    d
  811.     jnz    zxrg
  812.     call    xndi
  813.  
  814. clos:    mvi    c,16        ;(10) close file
  815.     lxi    d,xfil        ;.XRF FCB
  816.     call    0005        ; - B D O S -
  817.     inr    a
  818.     rnz
  819.     lxi    h,cclo        ;'can''t close'
  820.     jmp    ferm        ;final (error) message
  821.  
  822. ;    Disregard .COM files
  823.  
  824. dcom:    mov    a,m
  825.     cpi    'C'
  826.     rnz
  827.     inx    h
  828.     mov    a,m
  829.     cpi    'O'
  830.     rnz
  831.     inx    h
  832.     mov    a,m
  833.     cpi    'M'
  834.     rnz
  835.     lxi    h,M6        ;".COM file disregarded"
  836.     call    mssg        ;message to console
  837.     xra    a
  838.     ret
  839.  
  840. ;    Disregard .CMD files
  841.  
  842. dcmd:    mov    a,m
  843.     cpi    'C'
  844.     rnz
  845.     inx    h
  846.     mov    a,m
  847.     cpi    'M'
  848.     rnz
  849.     inx    h
  850.     mov    a,m
  851.     cpi    'D'
  852.     rnz
  853.     lxi    h,M7        ;".CMD file disregarded"
  854.     call    mssg        ;message to console
  855.     xra    a
  856.     ret
  857.  
  858. ;    Disregard .XRF files
  859.  
  860. dxrf:    mov    a,m
  861.     cpi    'X'
  862.     rnz
  863.     inx    h
  864.     mov    a,m
  865.     cpi    'R'
  866.     rnz
  867.     inx    h
  868.     mov    a,m
  869.     cpi    'F'
  870.     rnz
  871.     lxi    h,M9        ;".XRF file disregarded"
  872.     call    mssg        ;message to console
  873.     xra    a
  874.     ret
  875.  
  876. ;    Advance to next alternative
  877.  
  878. nexx:    mov    e,m
  879.     inx    h
  880.     mov    d,m
  881.     xchg
  882. next:    mov    a,m
  883.     ora    a
  884.     rz
  885.     inx    h
  886.     call    enda
  887.     rz
  888.     call    begb
  889.     jz    nexx
  890.     jmp    next
  891.  
  892. ;    Block fill with C B's starting at (HL).
  893.  
  894. fiuc:    mov    m,b
  895.     inx    h
  896.     dcr    c
  897.     jnz    fiuc        ;block fill
  898.     ret
  899.  
  900. ;    Block move of C bytes from (DE) to (HL).
  901.  
  902. miuc:    ldax    d
  903.     mov    m,a
  904.     inx    d
  905.     inx    h
  906.     dcr    c
  907.     jnz    miuc        ;block move
  908.     ret
  909.  
  910. ;    Read and semicompile the keyword.
  911.  
  912. meuv:    call    gkey
  913.     cpi    CR
  914.     jz    gkey        ;remove following LF
  915.     cpi    01AH        ;^Z
  916.     rz            ;end of file
  917.     mov    m,a
  918.     inx    h
  919.     cpi    TAB
  920.     jnz    mvnt
  921.     mvi    a,HT
  922. mvnt:    stax    d
  923.     inx    d
  924.     cpi    RBR
  925.     jz    mvrb
  926.     cpi    RSQ
  927.     jz    mvrb
  928.     cpi    LBR
  929.     jz    mvlb
  930.     cpi    LSQ
  931.     jz    mvlb
  932.     jmp    meuv
  933.  
  934. mvrb:    xthl
  935.     mov    m,e
  936.     inx    h
  937.     mov    m,d
  938.     pop    h
  939.     jmp    meuv
  940.  
  941. mvlb:    push    d
  942.     inx    d
  943.     inx    d
  944.     jmp    meuv
  945.  
  946. ;    Move and semi-compile the command line.
  947. ;        HL points to the command line
  948. ;        DE points to the pattern buffer
  949. ;        copy until a zero byte is found
  950.  
  951. muve:    mov    a,m
  952.     cpi    TAB
  953.     jnz    munt
  954.     mvi    a,HT
  955. munt:    stax    d
  956.     inx    h
  957.     inx    d
  958.     cpi    RBR
  959.     jz    murb
  960.     cpi    RSQ
  961.     jz    murb
  962.     cpi    LBR
  963.     jz    mulb
  964.     cpi    LSQ
  965.     jz    mulb
  966. must:    ora    a
  967.     jnz    muve
  968.     ret
  969.  
  970. murb:    xthl
  971.     mov    m,e
  972.     inx    h
  973.     mov    m,d
  974.     pop    h
  975.     jmp    must
  976.  
  977. mulb:    push    d
  978.     inx    d
  979.     inx    d
  980.     jmp    must
  981.  
  982. ;    Check balance of []'s and {}'s.
  983.  
  984. bala:    push    h
  985.     push    b
  986.     lxi    b,0101H
  987. balb:    mov    a,m
  988.     inx    h
  989.     cpi    LSQ
  990.     jnz    balc
  991.     inr    b
  992.     jmp    balb
  993. balc:    cpi    RSQ
  994.     jnz    bald
  995.     dcr    b
  996.     jz    balx
  997.     jmp    balb
  998. bald:    cpi    LBR
  999.     jnz    bale
  1000.     inr    c
  1001.     jmp    balb
  1002. bale:    cpi    RBR
  1003.     jnz    balf
  1004.     dcr    c
  1005.     jz    balx
  1006.     jmp    balb
  1007. balf:    ora    a
  1008.     jnz    balb
  1009.     mov    a,c
  1010.     cpi    01
  1011.     jnz    balx
  1012.     mov    a,b
  1013.     cpi    01
  1014.     pop    b
  1015.     pop    h
  1016.     rz
  1017. balx:    lxi    h,M3        ;"bad pattern"
  1018.     jmp    ferm        ;final (error) message
  1019.  
  1020. ;    Check for termination of alternative.
  1021.  
  1022. enda:    cpi    ORR
  1023.     rz
  1024. endb:    cpi    RSQ
  1025.     rz
  1026.     cpi    RBR
  1027.     rz
  1028.     ora    a
  1029.     ret
  1030.  
  1031. ;    Check for beginning of alternative.
  1032.  
  1033. bega:    cpi    ORR
  1034.     rz
  1035. begb:    cpi    LSQ
  1036.     rz
  1037.     cpi    LBR
  1038.     ret
  1039.  
  1040. ;    Check for null alternative.
  1041.  
  1042. nula:    push    h
  1043.     call    nulb
  1044.     pop    h
  1045.     ret
  1046. nulb:    mov    a,m
  1047.     inx    h
  1048.     ora    a
  1049.     rz
  1050.     call    bega
  1051.     jnz    nulb
  1052.     mov    a,m
  1053.     call    enda
  1054.     jnz    nulb
  1055.     jmp    balx
  1056.  
  1057. ;    Check for given expression.
  1058.  
  1059. chek:    ldax    d
  1060.     inx    d
  1061.     call    enda
  1062.     rz
  1063.     mov    b,a
  1064.     mov    a,m
  1065.     cpi    CR
  1066.     jz    chno
  1067.     mov    a,b
  1068.     cpi    LBR
  1069.     jz    chlb
  1070.     cpi    LSQ
  1071.     jz    chsq
  1072.     mov    c,m
  1073.     inx    h
  1074.     cpi    QUE
  1075.     jz    chek
  1076.     cpi    ALF
  1077.     jz    chal
  1078.     cmp    c
  1079.     jz    chek
  1080.     mov    b,a
  1081.     mov    a,c
  1082.     cpi    'a'
  1083.     jc    chno
  1084.     cpi    '{'
  1085.     jnc    chno
  1086.     ani    05FH
  1087.     cmp    b
  1088.     jz    chek
  1089. chno:    ori    0FFH
  1090.     ret
  1091.  
  1092. ;    Check alphanumeric.
  1093.  
  1094. chal:    mov    a,c
  1095.     cpi    '0'
  1096.     jc    chno
  1097.     cpi    ':'
  1098.     jc    chek
  1099.     cpi    'A'
  1100.     jc    chno
  1101.     cpi    '['
  1102.     jc    chek
  1103.     cpi    'a'
  1104.     jc    chno
  1105.     cpi    '{'
  1106.     jc    chek
  1107.     jmp    chno
  1108.  
  1109. ;    Check list of alternatives.
  1110.  
  1111. chsq:    mov    c,l
  1112.     mov    b,h
  1113.     lhld    sqxx
  1114.     push    h
  1115.     lhld    sqaa
  1116.     push    h
  1117.     lhld    sqzz
  1118.     push    h
  1119.     mov    l,c
  1120.     mov    h,b
  1121.     shld    sqxx
  1122.     xchg
  1123.     mov    e,m
  1124.     inx    h
  1125.     mov    d,m
  1126.     inx    h
  1127.     shld    sqaa
  1128.     xchg
  1129.     shld    sqzz
  1130. chaa:    lhld    sqxx
  1131.     call    chek
  1132.     jz    chff
  1133. chbb:    lhld    sqaa        ;fail so find next alternative
  1134. chcc:    call    next
  1135.     cpi    RSQ
  1136.     jz    chdd        ;no more alternatives, so fail
  1137.     cpi    ORR
  1138.     jnz    chcc
  1139.     shld    sqaa
  1140.     xchg
  1141.     jmp    chaa        ;try next alternative
  1142. chdd:    lhld    sqxx
  1143.     ori    0FFH
  1144. chee:    mov    c,l
  1145.     mov    b,h
  1146.     pop    h
  1147.     shld    sqzz
  1148.     pop    h
  1149.     shld    sqaa
  1150.     pop    h
  1151.     shld    sqxx
  1152.     mov    l,c
  1153.     mov    h,b
  1154.     ret
  1155. chff:    xchg            ;good alternative, try rest
  1156.     lhld    sqzz
  1157.     xchg
  1158.     call    chek
  1159.     jz    chee
  1160.     jmp    chbb
  1161.  
  1162. ;    Check iterative pattern.
  1163.  
  1164. chlb:    mov    c,l
  1165.     mov    b,h
  1166.     lhld    text
  1167.     push    h
  1168.     lhld    texx
  1169.     push    h
  1170.     lhld    rest
  1171.     push    h
  1172.     lhld    rept
  1173.     push    h
  1174.     lhld    repp
  1175.     push    h
  1176.     mov    l,c
  1177.     mov    h,b
  1178.     shld    text
  1179.     shld    texx
  1180.     xchg
  1181.     mov    e,m
  1182.     inx    h
  1183.     mov    d,m
  1184.     inx    h
  1185.     shld    rept
  1186.     shld    repp
  1187.     xchg
  1188.     shld    rest
  1189. chlc:    lhld    rest
  1190.     xchg
  1191.     lhld    text
  1192.     call    chek        ;check rest
  1193.     jz    chzz
  1194. chii:    lhld    rept        ;rest failed
  1195.     xchg
  1196.     lhld    text        ;keep same text
  1197.     call    chek        ;try out the repeater
  1198.     jnz    choo
  1199.     shld    text        ;repeater worked, record progress
  1200.     lhld    repp        ;start alternatives over again
  1201.     shld    rept
  1202.     jmp    chlc
  1203. choo:    lhld    rept        ;repeater failed, try next
  1204. chxx:    call    next
  1205.     cpi    RBR
  1206.     jz    chyy        ;this was the last, quit
  1207.     cpi    ORR
  1208.     jnz    chxx
  1209.     shld    rept
  1210.     jmp    chii
  1211. chyy:    lhld    texx
  1212.     ori    00        ;emphasize the RBR
  1213. chzz:    mov    c,l
  1214.     mov    b,h
  1215.     pop    h
  1216.     shld    repp
  1217.     pop    h
  1218.     shld    rept
  1219.     pop    h
  1220.     shld    rest
  1221.     pop    h
  1222.     shld    texx
  1223.     pop    h
  1224.     shld    text
  1225.     mov    l,c
  1226.     mov    h,b
  1227.     ret
  1228.  
  1229. M1:    db    'The command line',CR,LF,CR,LF
  1230.     db    '     FFYNDE [D:]FILE.EXT [E:]KEY.SYM LABEL',CR,LF,CR,LF
  1231.     db    'will search through all instances of FILE.EXT (which',CR,LF
  1232.     db    'may be an ambiguous reference) on disk D for lines',CR,LF
  1233.     db    'containing keywords taken from KEY.SYM (whose disk may',CR,LF
  1234.     db    'be specified). Any of these keywords may be regular',CR,LF
  1235.     db    'expressions. Then the whole family of files will be',CR,LF
  1236.     db    'searched for each line in KEY, whose default extension',CR,LF
  1237.     db    'is SYM. Results will be shown on the console and placed',CR,LF
  1238.     db    'in [E:]KEY.XRF. LABEL, a regular expression too, is a',CR,LF
  1239.     db    'reference for relative line numbers; if it is omitted',CR,LF
  1240.     db    'lines will be numbered serially in each file. Regular',CR,LF
  1241.     db    'expressions are formed as follows:',CR,LF
  1242.     db    '     [p1!p2!...!pn]  alternative strings',CR,LF
  1243.     db    '     {p1!p2!...!pn}  repeated alternatives',CR,LF
  1244.     db    '     ? any single character',CR,LF
  1245.     db    '     @ for any alphanumeric: a-z, A-Z, 0-9',CR,LF
  1246.     db    '     _ in place of horizontal tab',CR,LF
  1247.     db    'Squeezed files will be searched as well as unsqueezed',CR,LF
  1248.     db    'ones. Use ^C to quit, any other key skips rest of file.',CR,LF
  1249.     db    00
  1250.  
  1251. M2:    db    'FFYNDE.COM 08/01/84 ICUAP',CR,LF,00
  1252.  
  1253. M3:    db    '-- Bad Pattern --',00
  1254.  
  1255. M4:    db    CR,LF,'-- Search Terminated --',00
  1256.  
  1257. M5:    db    ' -- Remainder of File Skipped --',CR,LF,00
  1258.  
  1259. M6:    db    '.COM file disregarded.',CR,LF,00
  1260.  
  1261. M7:    db    '.CMD file disregarded.',CR,LF,00
  1262.  
  1263. M8:    db    ' -- Code Table Won''t Fit --',CR,LF,00
  1264.  
  1265. M9:    db    '.XRF file disregarded.',CR,LF,00
  1266.  
  1267. nkey:    db    ' -- Can''t Open Keyword File --',CR,LF,00
  1268.  
  1269. yexi:    db    ' -- Crossreference File Already Exists --',CR,LF,00
  1270.  
  1271. nxrf:    db    ' -- Can''t Open Crossreference File --',CR,LF,00
  1272.  
  1273. xwre:    db    ' -- Write Error in Crossreference File --',CR,LF,00
  1274.  
  1275. cclo:    db    ' -- Can''t Close Crossreference File --',CR,LF,00
  1276.  
  1277. enth:    ds    1        ;search-again counter
  1278. sfam:    db    'DFilenameEXT',00
  1279.     ds    20
  1280.  
  1281. sqxx:    ds    2
  1282. sqaa:    ds    2
  1283. sqzz:    ds    2
  1284. text:    ds    2
  1285. texx:    ds    2
  1286. rest:    ds    2
  1287. rept:    ds    2
  1288. repp:    ds    2
  1289. lapo:    ds    2        ;label pointer
  1290. kwdi:    db    'Keyword is:  '
  1291. keyr:    ds    64        ;raw keyword
  1292. hesq:    db    '[original] : '
  1293. uzfn:    db    'original.xxx'    ;unsqueezed file's name
  1294. crlf:    db    CR,LF,00
  1295. fhed:    db    '------> File '
  1296. fnam:    db    'xxxxxxxx.'    ;filename
  1297. fext:    db    'xxx',CR,LF,00    ;file extension
  1298. llbl:    db    '      +'
  1299. lnum:    db    '         ',00    ;line number
  1300. lzer:    db    '   0'        ;zero line for counter
  1301. ftot:    db    '      lines found',CR,LF,00
  1302. dtot:    db    '      instances in the entire disk',CR,LF,00
  1303. ktot:    db    '      keywords processed',CR,LF,00
  1304.     db    00        ;fence for line buffer
  1305. lbuf:    ds    85H        ;line buffer
  1306. dens:    ds    1        ;z/nz = un/squeezed
  1307. roby:    ds    1        ;rotating byte
  1308. roco:    ds    1        ;rotation count
  1309. mult:    ds    1        ;repeat factor
  1310. lach:    ds    1        ;last character read
  1311. ictr:    ds    2        ;input counter
  1312. iptr:    ds    2        ;input pointer
  1313. ibuf:    ds    isiz        ;input buffer
  1314. kfil:    ds    33        ;keyword FCB
  1315. kctr:    ds    2        ;keyword counter
  1316. kptr:    ds    2        ;keyword pointer
  1317. kbuf:    ds    csiz        ;keyword buffer
  1318. xfil:    ds    33        ;.XRF FCB
  1319. xctr:    ds    2        ;crossreference counter
  1320. xptr:    ds    2        ;crossreference pointer
  1321. xbuf:    ds    csiz        ;crossreference buffer
  1322. patt:    ds    256        ;command line pattern
  1323. kwrd:    ds    256        ;keyword pattern
  1324. code:    ds    4*hsiz        ;Huffman code table
  1325.  
  1326.     ds    100        ;stack area
  1327. stak:    ds    2        ;initialize stack pointer
  1328. fini:    ds    0
  1329.  
  1330.     end
  1331.  
  1332.