home *** CD-ROM | disk | FTP | other *** search
-
-
- ; ----------------------------------------------------------
- ; Reassembly of FIND.COM, which was originally extracted
- ; from the CBBS(R) package available from Ward Christensen
- ; and Randy Suess. However, considerable rearrangement has
- ; taken place, most notably the following:
- ; - <no file name> results in a screen of information
- ; - the search pattern may be a regular expression
- ; - instance count reported, both per file and globally
- ; To achieve compatibility with MicroShell the vertical bar
- ; was replaced by exclamation point; all syntactic elements
- ; are defined by EQU's and may be redefined. LABEL!PATTERN
- ; is checked for balanced parentheses and non-null arguments
- ; to forestall the most common failure modes. Had MicroShell
- ; not been available, an option to direct the output to some
- ; disk file would probably have been included. STUTE.ASM
- ; differs from FIND in that the patterns found are replaced
- ; by a constant rather than just being located.
- ;
- ; STUTE.ASM Copyright (C) 1983
- ; Universidad Autonoma de Puebla
- ;
- ; [Harold V. McIntosh, 28 February 1983]
- ; ----------------------------------------------------------
-
- HT equ 09H ;horizontal tab
- LF equ 0AH ;line feed
- CR equ 0DH ;carriage return
- KZ equ 1AH ;^Z
-
- ; Delimiters for the command line
-
- LSQ equ '[' ;begin alternative list
- RSQ equ ']' ;end alternative list
- LBR equ '{' ;begin iterated expression
- RBR equ '}' ;end iterated expression
- ORR equ '!' ;separate alternatives
-
- ; Representatives of characters or classes.
-
- TAB equ '_' ;substitute for tab
- QUE equ '?' ;represent any byte
- ALF equ '@' ;represent any alphanumeric
-
- ; CPM locations and parameters
-
- cfcb equ 005CH ;CP/M's file control block
- cblk equ 007CH ;CP/M's block counter
- csiz equ 0080H ;CP/M's record size
- cbuf equ 0080H ;CP/M's record buffer
- ksiz equ 26 ;sector capacity of IN buffer
- isiz equ ksiz*128
- osiz equ 128
-
- ; -------------
- org 0100H
- ; -------------
-
- begn: lxi h,0000
- dad sp
- shld stak
- lxi sp,stak
- lda cfcb+1 ;file name
- cpi ' '
- jnz X0143
- lxi h,tuto ;tutorial message
- call mssg
- jmp gbye
-
- X0143: lxi h,logo ;identification line
- call mssg
- mvi c,12
- lxi d,cfcb ;CP/M's FCB
- lxi h,file ;generic filename
- call miuc
- lda file ;generic filename
- sta kfil ;backup file (.BAK)
- sta ifil ;input file (.EXT)
- sta ofil ;output file (.$$$)
- sta ufil ;active output (.$$$)
- xra a
- sta enth
- lxi h,cbuf ;CP/M's record buffer
- mov e,m
- mov c,e
- mov d,a
- xchg
- inx d
- dad d
- mov m,a
- xchg
- X0152: inx h
- dcr c
- mov a,m
- ora a
- jz X029C
- cpi ' '
- jnz X0152
- inx h
- call bala ;check balance of [], {}.
- call nula ;check for null alternatives
- lxi d,patt ;command line pattern
- call muve
- xchg
- dcx h
- shld sund
- mvi c,4
- lxi d,lzer
- lxi h,dtot
- call miuc
- lxi h,patt ;command line pattern
- shld papo
- call next
- shld supo ;substitute pointer
-
- ; Scan the directory for file names.
-
- prep: xra a
- inr a
- sta dctr ;directory counter
- lxi h,diry ;directory extract
- shld dptr ;directory pointer
- push h
- mvi c,26 ;(1A) set DMA address
- lxi d,cbuf ;CP/M's record buffer
- call 0005 ; - B D O S -
-
- mvi c,17 ;(11) search once
- lxi d,file ;generic filename
- call 0005 ; - B D O S -
-
- fnth: pop h
- inr a
- jz scan ;all relevant files located
- push h
- dcr a
- ani 03
- add a
- add a
- add a
- add a
- add a
- adi 81H
- mov e,a
- mvi d,00
- lxi h,8
- dad d
- push h
- mov a,m
- cpi 'B'
- jnz nbak
- inx h
- mov a,m
- cpi 'A'
- jnz nbak
- inx h
- mov a,m
- cpi 'K'
- pop h
- jz omit
- jmp nbac
- nbak: pop h
- nbac: mvi a,'$'
- cmp m
- jnz ndol
- inx h
- cmp m
- jnz ndol
- inx h
- cmp m
- jz omit
- ndol: mvi c,12
- pop h
- call miuc
- push h
- lxi h,dctr ;directory counter
- inr m
-
- omit: mvi c,18 ;(12) search again
- lxi d,file ;generic filename
- call 0005 ; - B D O S -
-
- jmp fnth
-
- ; We're all done.
-
- done: lxi h,dtot
- call mssg
- gbye: lhld stak
- sphl
- ret
-
- ; A prospective file has been located
-
- scan: lxi h,dctr
- dcr m
- jz done
- lhld dptr
- xchg
- lxi h,12
- dad d
- shld dptr
- push d
-
- mvi c,8
- pop d
- push d
- lxi h,kfil+1 ;backup file (.BAK)
- call miuc
-
- mvi c,11
- pop d
- push d
- lxi h,ifil+1 ;input file (.EXT)
- call miuc
-
- mvi c,8
- pop d
- push d
- lxi h,ofil+1 ;output file (.$$$)
- call miuc
-
- mvi c,8
- pop d
- push d
- lxi h,ufil+1 ;active output (.$$$)
- call miuc
-
- mvi c,12
- pop d
- lxi h,cfcb+1 ;CP/M's file control block
- call miuc
-
- mvi c,19 ;(13) delete file
- lxi d,kfil ;backup file (.BAK)
- call 0005 ; - B D O S -
-
- mvi c,19 ;(13) delete file
- lxi d,ofil ;output file (.$$$)
- call 0005 ; - B D O S -
-
- mvi c,22 ;(16) create file
- lxi d,ufil ;active output (.$$$)
- call 0005 ; - B D O S -
- mvi a,00
- sta urec
-
- mvi c,15 ;(0F) open file
- lxi d,cfcb ;CP/M's FCB
- call 0005 ; - B D O S -
- inr a
- jz gbye ;quit [without message]
- xra a
- sta cblk ;block pointer
-
- mvi c,4
- lxi d,lzer
- lxi h,lnum ;'line number'
- call miuc
- mvi c,4
- lxi d,lzer
- lxi h,ftot ;'file total'
- call miuc
- mvi c,8
- lxi d,cfcb+1 ;file name
- lxi h,fnam ;'file name'
- call miuc
- mvi c,3
- lxi d,0065H ;extension
- lxi h,fext ;'file extension'
- call miuc
- lxi h,fhed
- call mssg ;message to console
- lxi b,2006H ;six spaces
- lxi h,llbl
- call fiuc ;fill until count
-
- X01C2: lxi h,0000
- shld ictr
- lxi h,0080H
- shld octr
- lxi h,ubuf
- shld optr
- X01C8: lxi h,lnum+3 ;increment l.c.
- call inco ;increment line counter
- lxi h,lbuf ;line buffer
- mvi b,0FFH
- X01E0: inr b
- jm X01FD
- push b
- push h
- call inch ;char from big bffr to line bffr
- pop h
- pop b
- mov m,a
- inx h
- cpi KZ
- jnz X01E8
- lxi h,ftot
- call mssg
-
- ; Close out last, incomplete record.
-
- lare: lhld octr
- mov a,h
- ora l
- jz clof
- mvi a,1AH
- call ouch
- jmp lare
-
- clof: mvi c,21 ;(15) write one record
- lxi d,ufil ;active output (.$$$)
- call 0005 ; - B D O S -
-
- mvi c,16 ;(10) close file
- lxi d,ufil ;active output (.$$$)
- call 0005 ; - B D O S -
-
- mvi c,23 ;(17) rename file
- lxi d,ifil ;input file (.EXT)
- call 0005 ; - B D O S -
-
- mvi c,23 ;(17) rename file
- lxi d,ofil ;output file (.$$$)
- call 0005 ; - B D O S -
-
- jmp scan
-
- X01E8: cpi LF
- jnz X01E0
- jmp X0202
-
- X01FD: mvi m,CR
- inx h
- mvi m,LF
- inx h
-
- ; Check console for termination request. If one
- ; is present, clear it out before leaving.
-
-
- X0202: mvi m,00 ;guarantee right hand fence
- mvi c,11 ;(0B) console status
- call 0005 ; - B D O S -
- ora a
- jz culi
- mvi c,1 ;(01) read console
- call 0005 ; - B D O S -
- lxi h,M4 ;"search terminated"
- call mssg
- jmp gbye
-
- ; Scan the current line.
-
- culi: lxi h,lbuf ;line buffer
- shld alfa
- shld beta
- X021A: lhld papo ;substitute pointer
- xchg
- lhld beta
- mov a,m
- cpi CR
- jz nuli
- call chek
- jnz fail
- push d
- push h
- lxi h,llbl
- call mssg
- lxi h,lbuf
- call mssg
- lxi h,ftot+3
- call inco
- lxi h,dtot+3
- call inco
- lhld beta
- xchg
- lhld alfa
- call ouli
- lhld sund
- xchg
- lhld supo
- call ouli
- pop h
- shld alfa
- dcx h
- shld beta
- pop d
- fail: lhld beta
- inx h
- shld beta
- jmp X021A
-
- nuli: lhld beta
- inx h
- inx h
- xchg
- lhld alfa
- call ouli
- jmp X01C8 ;increment l.c. at X026A
-
- ; Increment ASCII counter at (HL-3).
-
- inco: mov a,m
- ori 30H
- inr a
- mov m,a
- cpi ':'
- rnz
- mvi m,'0'
- dcx h
- jmp inco
-
- ; Memory to console
-
- mssg: mov e,m
- inx h
- push h
- mvi c,2 ;(02) write console
- call 0005 ; - B D O S -
- pop h
- mov a,m
- ora a
- jnz mssg
- ret
-
- X029C: lxi h,M3 ;"bad pattern"
- call mssg
- jmp gbye
-
- inch: lhld ictr
- mov a,h
- ora l
- cz indi ;disk to IN area
- lhld ictr
- dcx h
- shld ictr
- lhld iptr
- mov a,m
- cpi KZ
- rz
- inx h
- shld iptr
- ret
-
- indi: mvi b,ksiz
- lxi h,isiz
- shld ictr
- lxi h,ibuf
- shld iptr
- indd: mvi m,KZ
- push h
- push b
- xchg
- mvi c,26 ;(1A) set DMA address
- call 0005 ; - B D O S -
- lxi d,cfcb ;CP/M's file control block
- mvi c,20 ;(14) read one record
- call 0005 ; - B D O S -
- pop b
- pop h
- ora a
- rnz
- dcr b
- rz
- lxi d,csiz ;CP/M's record size
- dad d
- jmp indd
-
- ; Send a "line" [(HL) to (DE)] to out file
-
- ouli: mov a,e
- sub l
- mov c,a
- mov a,d
- sbb h
- mov b,a
- oulj: mov a,b
- ora c
- rz
- mov a,m
- call ouch
- dcx b
- inx h
- jmp oulj
-
- ; Send one character to the output file, conserve BC, HL
-
- ouch: push b
- push h
- push psw
- lhld octr
- mov a,h
- ora l
- cz oudi ;OUT area to disk
- lhld octr
- dcx h
- shld octr
- pop psw
- lhld optr
- mov m,a
- inx h
- shld optr
- pop h
- pop b
- ret
-
- oudi: lxi h,osiz
- shld octr
- lxi h,ubuf
- shld optr
- xchg
- mvi c,26 ;(1A) set DMA address
- call 0005 ; - B D O S -
- lxi d,ufil ;active output (.$$$)
- mvi c,21 ;(15) write one record
- call 0005 ; - B D O S -
- ora a
- ret
-
- ; Advance to next alternative
-
- nexx: mov e,m
- inx h
- mov d,m
- xchg
- next: mov a,m
- ora a
- rz
- inx h
- call enda
- rz
- call begb
- jz nexx
- jmp next
-
- ; Fill (with B) until count (C).
-
- fiuc: mov m,b
- inx h
- dcr c
- jnz fiuc
- ret
-
- miuc: ldax d
- mov m,a
- inx d
- inx h
- dcr c
- jnz miuc
- ret
-
- ; Move and semi-compile the command line.
-
- muve: mov a,m
- cpi TAB
- jnz munt
- mvi a,HT
- munt: stax d
- inx h
- inx d
- cpi RBR
- jz murb
- cpi RSQ
- jz murb
- cpi LBR
- jz mulb
- cpi LSQ
- jz mulb
- must: dcr c
- jnz muve
- ret
-
- murb: xthl
- mov m,e
- inx h
- mov m,d
- pop h
- jmp must
-
- mulb: push d
- inx d
- inx d
- jmp must
-
- ; Check balance of []'s and {}'s.
-
- bala: push h
- push b
- lxi b,0101H
- balb: mov a,m
- inx h
- cpi LSQ
- jnz balc
- inr b
- jmp balb
- balc: cpi RSQ
- jnz bald
- dcr b
- jz balx
- jmp balb
- bald: cpi LBR
- jnz bale
- inr c
- jmp balb
- bale: cpi RBR
- jnz balf
- dcr c
- jz balx
- jmp balb
- balf: ora a
- jnz balb
- mov a,c
- cpi 01
- jnz balx
- mov a,b
- cpi 01
- pop b
- pop h
- rz
- balx: lxi h,M3 ;"bad pattern"
- call mssg
- jmp gbye ;PDL unbalanced but doesn't matter
-
- ; Check for termination of alternative.
-
- enda: cpi ORR
- rz
- endb: cpi RSQ
- rz
- cpi RBR
- rz
- ora a
- ret
-
- ; Check for beginning of alternative.
-
- bega: cpi ORR
- rz
- begb: cpi LSQ
- rz
- cpi LBR
- ret
-
- ; Check for null alternative.
-
- nula: push h
- call nulb
- pop h
- ret
- nulb: mov a,m
- inx h
- ora a
- rz
- call bega
- jnz nulb
- mov a,m
- call enda
- jnz nulb
- jmp balx
-
- ; Check for given expression.
-
- chek: ldax d
- inx d
- call enda
- rz
- mov b,a
- mov a,m
- cpi CR
- jz chno
- mov a,b
- cpi LBR
- jz chlb
- cpi LSQ
- jz chsq
- mov c,m
- inx h
- cpi QUE
- jz chek
- cpi ALF
- jz chal
- cmp c
- jz chek
- mov b,a
- mov a,c
- cpi 'a'
- jc chno
- cpi '{'
- jnc chno
- ani 05FH
- cmp b
- jz chek
- chno: ori 0FFH
- ret
-
- ; Check alphanumeric.
-
- chal: mov a,c
- cpi '0'
- jc chno
- cpi ':'
- jc chek
- cpi 'A'
- jc chno
- cpi '['
- jc chek
- cpi 'a'
- jc chno
- cpi '{'
- jc chek
- jmp chno
-
- ; Check list of alternatives.
-
- chsq: mov c,l
- mov b,h
- lhld sqxx
- push h
- lhld sqaa
- push h
- lhld sqzz
- push h
- mov l,c
- mov h,b
- shld sqxx
- xchg
- mov e,m
- inx h
- mov d,m
- inx h
- shld sqaa
- xchg
- shld sqzz
- chaa: lhld sqxx
- call chek
- jz chff
- chbb: lhld sqaa ;fail so find next alternative
- chcc: call next
- cpi RSQ
- jz chdd ;no more alternatives, so fail
- cpi ORR
- jnz chcc
- shld sqaa
- xchg
- jmp chaa ;try next alternative
- chdd: lhld sqxx
- ori 0FFH
- chee: mov c,l
- mov b,h
- pop h
- shld sqzz
- pop h
- shld sqaa
- pop h
- shld sqxx
- mov l,c
- mov h,b
- ret
- chff: xchg ;good alternative, try rest
- lhld sqzz
- xchg
- call chek
- jz chee
- jmp chbb
-
- ; Check iterative pattern.
-
- chlb: mov c,l
- mov b,h
- lhld text
- push h
- lhld texx
- push h
- lhld rest
- push h
- lhld rept
- push h
- lhld repp
- push h
- mov l,c
- mov h,b
- shld text
- shld texx
- xchg
- mov e,m
- inx h
- mov d,m
- inx h
- shld rept
- shld repp
- xchg
- shld rest
- chlc: lhld rest
- xchg
- lhld text
- call chek ;check rest
- jz chzz
- chii: lhld rept ;rest failed
- xchg
- lhld text ;keep same text
- call chek ;try out the repeater
- jnz choo
- shld text ;repeater worked, record progress
- lhld repp ;start alternatives over again
- shld rept
- jmp chlc
- choo: lhld rept ;repeater failed, try next
- chxx: call next
- cpi RBR
- jz chyy ;this was the last, quit
- cpi ORR
- jnz chxx
- shld rept
- jmp chii
- chyy: lhld texx
- ori 00 ;emphasize the RBR
- chzz: mov c,l
- mov b,h
- pop h
- shld repp
- pop h
- shld rept
- pop h
- shld rest
- pop h
- shld texx
- pop h
- shld text
- mov l,c
- mov h,b
- ret
-
- tuto: db 'The command line',CR,LF
- db ' STUTE D:FILE.EXT PATTERN!SKELETON',CR,LF
- db 'will search through all instances of FILE.EXT',CR,LF
- db '(which may be an ambiguous reference) on disk D',CR,LF
- db 'to find lines containing PATTERN. Such lines will',CR,LF
- db 'be shown on the console preceded by a line number,',CR,LF
- db 'classified by file. Whenever the regular expression',CR,LF
- db 'PATTERN is found, it will be replaced by the constant',CR,LF
- db 'SKELETON. The PATTERN may contain:',CR,LF
- db ' [p1!p2!...!pn] alternative strings',CR,LF
- db ' {p1!p2!...!pn} repeated alternatives',CR,LF
- db ' ? any single character',CR,LF
- db ' @ for any alphanumeric: a-z, A-Z, 0-9',CR,LF
- db ' _ in place of horizontal tab',CR,LF
- db 'A general PATTERN must be used with extreme caution',CR,LF
- db 'because the same constant will replace it, whatever',CR,LF
- db 'its form. The PATTERN may not involve more than one',CR,LF
- db 'single line, but more than one instance of the PATTERN',CR,LF
- db 'may occupy the same line.',CR,LF
- db 00
-
- logo: db 'STUTE.COM 28/FEB/83 ICUAP',CR,LF,00
-
- M3: db '-- Bad Pattern --',00
-
- M4: db CR,LF,'-- Substitution Terminated --',00
-
- ; The following file control segments are arranged in just
- ; the form shown so that they will be properly paired for
- ; the renaming which has to be done after closing each file.
-
- enth: ds 1
- file: db 'DFilenameEXT',00,00,00,00 ;generic filename
- ds 16
- ofil: db 'DFilename$$$',00,00,00,00 ;output file (.$$$)
- ifil: db 'DFilenameEXT',00,00,00,00 ;input file (.EXT)
- kfil: db 'DFilenameBAK',00,00,00,00 ;backup file (.BAK)
- ufil: db 'Dfilename$$$',00,00,00,00 ;active output (.$$$)
- ds 16
- urec: ds 1
- ubuf: ds 80H
- optr: ds 2
- octr: ds 2
-
- ; All the relevant files are located and noted before any
- ; substitutions are made, to avoid a newly created file
- ; being placed in the dictionary, being encountered again
- ; later on and then being processed a second time. The worst
- ; case would be to have to use all 64 files (minus one, for
- ; elbow room) in the directory.
-
- dctr: ds 1 ;directory counter
- dptr: ds 2 ;directory pointer
- diry: ds 1024 ;directory of file names, if needed
-
- ; Temporary storage for the regular expression parser.
-
- sqxx: ds 2
- sqaa: ds 2
- sqzz: ds 2
- text: ds 2
- texx: ds 2
- rest: ds 2
- rept: ds 2
- repp: ds 2
-
- alfa: ds 2
- beta: ds 2
-
- patt: ds 256 ;command line pattern
- ds 100 ;stack area
- stak: ds 2 ;initialize stack pointer
- papo: ds 2 ;pattern pointer
- supo: ds 2 ;substitute pointer
- sund: ds 2
- fhed: db '----> File '
- fnam: db 'xxxxxxxx.' ;filename
- fext: db 'xxx',CR,LF,00 ;file extension
- llbl: db ' +'
- lnum: db ' ',00
- lzer: db ' 0'
- ftot: db ' lines found',CR,LF,00
- dtot: db ' instances in the entire disk',CR,LF,00
- db 00 ;fence for line buffer
- lbuf: ds 85H ;line buffer
- ictr: ds 2
- iptr: ds 2
- ibuf: ds isiz
- fini: ds 0
-
- end
-
-