; SwatSymA.asm -- Companion to SwatSymB.bcpl ; Copyright Xerox Corporation 1982 ; Last modified March 23, 1982 6:17 PM by Boggs ; outgoing procedures .ent ScanSymBuffer .ent FindSym, ClosestPL, ClosestV ; incoming statics .bext p, s, a .srel ScanSymBuffer: .ScanSymBuffer FindSym: .FindSym ClosestPL: .ClosestPL ClosestV: .ClosestV .nrel ; ScanSymBuffer(ptr, endPtr, name) ; Scans memory in the region [ptr..endPtr) looking at symbols, ; and returns a pointer to a symbol that either matches name or ; extends to or beyond endPtr. name = 0 thisPtr = 1 frame = 2 endPtr = 3 nextPtr = 4 tempName = 5 tempLength = 6 ; Equivalent BCPL code: ; and ScanSymBuffer(ptr, endPtr, symbol) = valof ; [ ; let len = ptr>>String.length rshift 1 +1 ; if ptr+len uge endPtr resultis ptr ; if StringCompare(ptr, symbol) eq 0 resultis ptr ; ptr = ptr + len ; ] repeat .ScanSymBuffer: sta 3 1,2 jsr ssb ; ac3 -> table .blk 7 ssb: sta 0 nextPtr,3 ; save ptr sta 1 endPtr,3 ; save endPtr sta 2 frame,3 ; save frame lda 0 3,2 sta 0 name,3 ; save name ; Examine next symbol -- compute length nextSym:lda 2 nextPtr,3 ; get ptr to symbol sta 2 thisPtr,3 lda 0 0,2 lda 1 c177400 ands 1 0 ; thisPtr>>String.length movzr 0 0 ; rshift 1 inc 0 0 ; +1 sta 0 tempLength,3 ; length in words ; Check for symbol extending beyond end of buffer add 2 0 ; ac0← ptr+length sta 0 nextPtr,3 ; pointer to next symbol lda 1 endPtr,3 ; endPtr sltu 0 1 jmp exit ; extends to or beyond end, exit ; Compare first word of symbol (length and first character). ; Most mismatches should occur at this point. lda 0 0,2 ; get word from symbol lda 1 c177737 ; capitalize first character and 1 0 lda 1 @name,3 ; get word from name se 1 0 jmp nextSym ; did not match, advance to next symbol ; First word matched. Now prepare to check the rest of the name. lda 1 c177400 ands 1 0 ; # of characters in symbol movzr 0 0 szc ; if even then must handle garbage byte jmp scomp ; odd add 2 0 ; ac0 is address of last word of symbol sta 0 tempName,3 ; (out of index registers) lda 0 @tempName,3 ; pick up last word and 1 0 ; set low (garbage) byte to zero sta 0 @tempName,3 ; put it back scomp: lda 0 name,3 ; set up name pointer and length in temps sta 0 tempName,3 jmp ecomp ; Symbol/Name compare loop comp: inc 2 2 ; advance symbol pointer isz tempName,3 ; advance name pointer lda 0 0,2 ; get word from symbol lda 1 c157737 ; capitalize letters and 1 0 lda 1 @tempName,3 ; get word from name se 1 0 jmp nextSym ; did not match, advance to next symbol ecomp: dsz tempLength,3 ; decrement and test word count jmp comp ; continue ; Here to exit. ac3 -> ssb. exit: lda 0 thisPtr,3 ; return ptr lda 2 frame,3 ; recover frame lda 3 1,2 jmp 1,3 c177737: 177737 c157737: 157737 c177400: 177400 ; and FindSym(sym) be //asm coded for speed ; if sym>>Sym.builtIn eq 0 & sym>>Sym.inCache eq 0 & ; sym>>Sym.namePos eq p then s = sym .FindSym: sta 3 1,2 mov 0 3 ; sym lda 0 1,3 ; flag word lda 1 c600 ; flag mask and 1 0 szr ; either flag set? jmp FSExit ; yes. lda 0 0,3 ; sym.namePos lda 1 @.p ; p sne 0 1 ; same? sta 3 @.s ; s = sym FSExit: lda 3 1,2 jmp 1,3 c600: 600 .p: p .s: s ; and ClosestPL(sym) be //asm coded for speed ; if s>>Sym.value uls sym>>Sym.value & sym>>Sym.value ule a & ; s>>Sym.bank eq sym>>Sym.bank then s = sym .ClosestPL: sta 3 1,2 mov 0 3 ; sym sta 2 save2 lda 2 @.s ; s lda 0 3,2 ; s.value lda 1 3,3 ; sym.value sltu 0 1 jmp PLExit lda 0 @.a ; a sleu 1 0 jmp PLExit lda 0 1,3 ; sym.bank lda 1 1,2 ; s.bank lda 2 c3 and 2 0 and 2 1 sne 0 1 sta 3 @.s ; s = sym PLExit: lda 2 save2 lda 3 1,2 jmp 1,3 c3: 3 save2: 0 .a: a ; and ClosestV(sym) be //asm coded for speed ; if sym>>Sym.addr eq a then s = sym .ClosestV: sta 3 1,2 mov 0 3 ; sym lda 0 2,3 ; sym.addr lda 1 @.a ; a sne 0 1 sta 3 @.s ; s = sym lda 3 1,2 jmp 1,3 .end