; DirScanA.asm -- Scan directory buffer quickly ; Copyright Xerox Corporation 1979 ; Last modified July 12, 1979 9:56 AM by Taft .ent ScanDirBuffer .srel ScanDirBuffer: .ScanDirBuffer .nrel ; ScanDirBuffer(ptr, endPtr, sdb) ; Scans memory in the region [ptr..endPtr) looking at directory entries, ; and returns a pointer to some "interesting" directory entry. ; It is assumed that endPtr-ptr le 2000B. ; sdb is a ScanDirBuffer state structure: ; structure SDB: [ ; name word // -> name string, which must be all upper-case ; length word // number of words to check in the name string ; ignoreFree word // true to skip free blocks, false to stop on each ; scratch word 5 // scratch area used by ScanDirBuffer ; ] ; An interesting entry is one that: ; (1) is of dvTypeFile and matches name; ; (2) is of dvTypeFree and ignoreFree is false; ; (3) is not of dvTypeFile or dvTypeFree; or ; (4) extends to or beyond endPtr. ; structure of SDB: name = 0 length = 1 ignoreFree = 2 frame = 3 endPtr = 4 nextPtr = 5 tempName = 6 tempLength = 7 lDV = 6 .ScanDirBuffer: sta 3 1 2 lda 3 3 2 ; ac3← sdb sta 2 frame 3 ; save frame in sdb sta 0 nextPtr 3 ; save ptr sta 1 endPtr 3 ; save endPtr ; Examine next directory entry. ; First, extract length and examine type. nextDV: lda 2 nextPtr 3 ; get ptr to directory entry nextD1: lda 0 0 2 lda 1 c2000 ; dvTypeFile = 1 subz 1 0 snc ; if dvTypeFile, type bits become zero jmp freeDV ; dvTypeFree = 0 (the only type < 1) ; If type was other than dvTypeFile then ac0 is now ge 2000B. ; Hence the following test is not needed. ; sltu 0 1 ; jmp exit ; not dvTypeFile, exit ; Check for entry extending beyond end of buffer add 2 0 ; ac0← ptr+length lda 1 endPtr 3 ; endPtr sltu 0 1 jmp exit ; extends to or beyond end, exit sta 0 nextPtr 3 ; pointer to next directory entry ; Compare first word of name (length and first character). ; Most mismatches should occur at this point. lda 0 lDV 2 ; get word from entry lda 1 c177737 ; capitalize first character and 1 0 lda 1 @name 3 ; get word from name sub 1 0 szr jmp nextDV ; did not match, advance to next entry ; First word matched. Now prepare to check the rest of the name. lda 0 name 3 ; set up name pointer and length in temps sta 0 tempName 3 lda 0 length 3 sta 0 tempLength 3 jmp ecomp comp: inc 2 2 ; advance directory entry pointer isz tempName 3 ; advance name pointer lda 0 lDV 2 ; get word from entry lda 1 c157737 ; capitalize letters and 1 0 lda 1 @tempName 3 ; get word from name sub 1 0 szr jmp nextDV ; did not match, advance to next entry ecomp: dsz tempLength 3 ; decrement and test word count jmp comp ; continue ; Name matched entirely. Return pointer to directory entry. lda 0 length 3 ; number of words we checked sub 0 2 ; reset ptr to start of dir entry inc 2 2 jmp exit ; Here for free entry. Return it only if ignoreFree is false freeDV: add 1 0 ; restore length lda 1 ignoreFree 3 snz 1 1 jmp exit add 0 2 ; ac2← ptr+length lda 1 endPtr 3 ; endPtr sgeu 2 1 jmp nextD1 ; not at end yet, advance to next entry sub 0 2 ; restore ptr ; Here to exit. ac2 has pointer to directory entry, ac3 to sdb. exit: mov 2 0 ; return ptr lda 2 frame 3 ; recover frame lda 3 1 2 jmp 1 3 c177737: 177737 c157737: 157737 c2000: 2000 .end