// // File searching package // last edited October 29, 1980 9:31 PM // // Copyright Xerox Corporation 1979, 1980 get "streams.d" get "altofilesys.d" get "findintdefs.d" external // entries [ FindInitScan // (stream, buf, bufsize, fa) -> ssd FindNext // () -> ppos/not npages // Set up by FindCompile or FindCompileSoft findWriteReg // (reg, value) findJumpRam // (ac0, addr, ac3) -> (ac0, ac1, ac3) ] external // procedures used [ // OS GetScanStreamBuffer InitScanStream LnPageSize MoveBlock ] static [ @fSsd // ScanStream descriptor @fFa // FA for passing match position to caller @fPn // page number of current buffer @fBuf // current buffer @fAddr // current address within fBuf @fNchars // number of chars of data in fBuf @fOdd // 1 if scan ended on an odd byte // entries for FindComp @fNegK // -K+1, where K is pattern length - fuzz @fNphase // number of phases @fExitChar // exit character (both bytes) findWriteReg = 0 findJumpRam = 0 ] let FindInitScan(st, buf, bufsize, fa) = valof [ let logps = LnPageSize(st) let ps = 1 lshift logps fBuf = buf let bufs = fBuf+ps+1 // +1 to store exit char at end let nbufs = (bufsize-ps-1)/ps for i = 0 to nbufs-1 do fBuf!i = bufs+(i lshift logps) // *** The following statement is a kludge to overcome the inflexible // *** allocation policy of InitScanStream if nbufs gr 3 then nbufs = 3 fSsd = InitScanStream(st, fBuf, nbufs) fFa = fa fPn = 0 @fBuf = fExitChar fNchars = 0 fAddr = fBuf-1 fOdd = 1 findWriteReg(RnegK1, fNegK) if findJumpRam eq 0 then findJumpRam = table[ 55001b // sta 3 1,2 35003b // lda 3 3,2 JMPRAM 11001b // isz 1,2 3001b // jmp @1,2 ] findJumpRam(1777b, Reset) resultis fSsd ] let FindNext() = valof [ let link, nctr, phase = nil, nil, nil // preallocate for assembly code let sa = (FetchEven+1)-fOdd let next = table[ 55004b // STA 3 link,2 6406b // JSR @lvfindJumpRam 2 // 2 // nargs 45005b // STA 1 nctr,2 55006b // STA 3 phase,2 35004b // LDA 3 link,2 1401b // JMP 1,3 0 //lvfindJumpRam: ] next!7 = findJumpRam fAddr = next(fAddr, sa) fOdd = ((phase rshift 11) + phase) & 1 let p1 = (fAddr-fBuf)*2+fOdd if nctr ge 0 then // real match [ findJumpRam(5777b-(fOdd lshift 11), Reset) fFa>>FA.charPos = p1 resultis ((phase&1777b)-nctr+fNphase) rem fNphase // position within pattern ] test p1 eq fNchars ifso // real end of buffer [ unless findbuffer() resultis not fPn findWriteReg(Rphase, phase-1) // back up phase fOdd = 1 // force even fetch next ] ifnot // extraneous exit char [ findWriteReg(Rphase, (phase-1) xor 4000b) // invert even/odd flag ] ] repeat and findbuffer() = valof // Returns true if more data [ let buf = GetScanStreamBuffer(fSsd) if buf eq 0 resultis false fPn = fSsd>>SSD.pageNumber fAddr = fBuf-1 fNchars = fSsd>>SSD.numChars fFa>>FA.da = fSsd>>SSD.da fFa>>FA.pageNumber = fPn MoveBlock(fBuf, buf, (fNchars+1) rshift 1) // Ugly but necessary fBuf>>bytes^fNchars = fExitChar resultis true ]